Jump to content

Kas Ob.

  • Content Count

  • Joined

  • Last visited

  • Days Won


Kas Ob. last won the day on May 25

Kas Ob. had the most liked content!

Community Reputation

98 Excellent

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I remembered the worse of them all, clicking show Desktop aka minimize everything, and an application still there, most annoying thing, sadly the Delphi debugger do this without any sense of consideration i would love to see an animation like a hammer and a nail when it refuse to minimize.
  2. No imagination here just logic an make sense. OK, but how it is more complicated, on one hand Sleep doesn't have fixed interval ! right ? any other application running on Windows OS can ruin your timing by 16 fold, i saw it 1ms and saw it 15.625ms, these are the most popular. On other hand either that animation is slow and taking long time or very fast, in both cases a timer or background thread will be more appreciated and will not prevent the used from closing the app as as example or not clicking a button, or even worse buffering few clicks form the user then fire them afterward like machine gun. And again if it is one animation then one timer will do it, but if there is more then what more sleep calls, or the same one timer or even more timers, for me this is simple question and simple answer. 300ms delay in IDE autocomplete does feel very different from 200ms, don't you agree ?
  3. Also i didn't say this will solve the problem or will work as workaround. Sleep can no be used for timing anywhere, and in this application if it is being used as such then a confirmation is needed. Just like handling Windows control and custom drawing, as example, take Custom Draw events, like ListBox, some might implement to draw one item on every call or even draw the whole list with all the items, still the OS will send punch of draw messages, different messages for might be one or many items, some will simply pointing the X item is not selected followed by Y item selected, while the application just draw the lot twice.
  4. I do understand. I want the CPU to spike first, go full core, only after that the reason(s) for the stuttering can be identified or isolated, right now and until now all i got from the description is the CPU is doing nothing yet there is unresponsiveness in UI, after unhinge the CPU and processing loops without break, if the stutter still exist then this will mean a thing if not then it is a different thing and so on. If it is an one-to-one import for very old design like DOS then timing is suffer as modern OS and CPU behave differently and multitasking is shared responsibility between the application and OS, in old days your game should time the rendering and the input and give no concern about OS or other any applications running on the device. When i see a comment in the source right before Sleep(1) call with " // Relax CPU" then many variation comes to mind, relax for whom or to whom as this game is one thread and the OS will switch it when he see fit not waiting for such a sleep, this makes sense if such sleep is inside a never ending loop, is it ? All in all, i can't imagine (what ever) reason to call Sleep from main thread. think about it.
  5. Well said and well done but this : This is freaking beautiful, nice. Yesterday only i downloaded https://github.com/ericlangedijk/Lemmix at last and tried to build it, but it is not for older Delphi. This is tricky sometimes, but in your case it is very easy, in that PE tab there is Starting Address, pointing to the module created the thread, in your application there is only one started form your EXE, while when debugging in the IDE yes most likely it is the first one unless an imported DLL invoked one and the debugger captured it, Delphi Debugger leave the threads sorted as they being seen, while Process Explorer sort them by CPU usage by default, and its sort options doesn't have running time. That is not exactly what i said, i said BASS is capable to do all its operations in asynchronous, but only if told to do so, the documentation clear about threading like this not so special case ( from https://www.un4seen.com/doc/#bass/BASS_ChannelSetSync.html ) But now and reading more of BASS documentation i don't think it is the culprit here, because i am sure you did disable all the sound effect if there is any changes then you would already mentioned that. Now to the most important question Well evidently is not, and your application has one thread (main one) and from PE it is doing nothing, yet it is not responding in time, so what ? This project is half doomed to work on modern OS and that is by design, after reading the readme which is clearly is pointing that the structure based on DOS era application, where you must not let the thread go anywhere except looping over handling UI and draw/update the screen. There is huge misconception in this approach with assuming to be working on modern OS, from what caught my eye the application is abusing ApplicationIdle to process almost everything, like this I want to suggest something might be look stupid and might be in fact a stupid thing considering i can build or debug or investigate this deeper, but please try the following: 1) Make sure there is no Sleep calls at all ! everything single one of them , these you have to replace them with timers in needed 2) The core problem is this class and how it does lose control and regain it, when sleeping or out of execution there is no update and when it is activated it is doing small update step just to go into sleep again, (again and again sleep is the problem) 3) put a timer on where application idle or that TIdle is used and make it call the according "Application_Idle(Sender: TObject; var Done: Boolean)" manually instead of depending on the VCL library to do so, this means disabling the handler or work around it, then though it should at least show some CPU processing and greatly raise your FPS in your case the application UI responsiveness. Sender not used so you can fill it with nil, as for Done don't process it for first test, not sure if it should be useful at all, i mean even if an animation is done drawing and we can't(and must not) disable the timer as we emulating OnIdle so calling again is merely a simple check. 4) put these timers intervals at 1 ms, start there to see how animation are being drawn, tweaking this is most likely needed but lets find and understand the structure and logic first. Share your result with us ! ps: i can't say for sure about this TIdle, but there is something wrong about it and about having Application.OnIdle being assigned in few other places other than that TIdle, so there might be some conflict or miss handling, so try to replace the Idle handlers one by one , start with the working ones, just to understand the effect and side effect.
  6. Kas Ob.

    Release or Debug?

    You missed attaching this image as explanatory material Joking aside : How to use a script to add datetime on checkin like leaving the rversion 0 or whatever to minimize breaking changes, but with an extra string like 202405281850 ? Is that is easy/feasible with SVN ?
  7. This indicate long process and from the memory graph there is huge allocation(s), but no CPU spike also no spike in IO, this means the process or the main thread was waiting or sleeping, aka doing nothing. While this is concerning, Context Switches at 272k with 3 seconds of User Time, this is too much of thread switching while the code in user mode. See this is my ThunderBird (an old version before switching to Chromium means it is single process) , It was up and running for 6 hours and still doesn't have that much of switching while in CPU cycles used as half of the shown in your screen shot. I asked for 2 different shots to compare with some interval between them, so we can see if these context switches as still happening or stopped after loading the form, and fortunately your screenshot landed on your app main thread, which i didn't explicitly point it to fearing of spending time explaining stuff might not be relevant here, so if you will repost screenshot make sure to select that thread from your EXE. ps: if you will repeat the screenshot then first run Process Explorer as Administrator, i would helpful to see the kernel time. Anyway, and to what i do see: Your application is literally doing nothing, there is no intensive CPU usage at all, but there is two background threads i am concerned about, one from dsound usaualy indicate the directsound is playing or recording, in other words there is an audio operation in work. one from BASS.dll, but not sure about this as i am not familiar with bass, only general and past knowledge, so it might be relevant to the above or might not be. from the above i have a question : Are you playing sound(s) in the background or on mouse movement events ? (are you playing sound effects ?) What ever is the answer, try to stop all audio operation like playing sounds and see how does that impact the responsive of your UI, and please share your finding. One more point : to my knowledge BASS library is fully equipped with background threads handling/playing, so most its operations can be asynchronous, to me your unresponsiveness UI is a symptoms of long synchronous operations called from MainThread, the one that should not be doing much other than handling user input, UI, and essential OS calls/notifications, and of course drawing/updating UI (this drawing is more like slapping already rendered image on a canvas).
  8. That depends if you are doing some drawing, updating some visually elements... in other words if the updating the scroller is more than painting already cached images or change position of already ready to draw elements then use a thread to do it, then use the timer to do the paint or the update, but in both cases timer will solve your problem. Main thread is the first thread in your application the one handed the execution form OS starting the dpr code, and called Application.Run, this one is the only one should handle all your UI (VCL/FMX) and their events, MainThread is a name for specific thread and not some generic terminology. Also keep in mind that your MainThread is the one responsible for any stuttering or slow UI handling, so we need to free it from doing anything expensive or might take long time, its job is answering OS messages (aka user and OS input and your specific requests from the OS)as fast as possible, when that is full filled the UI will be smooth, fast and keep up with screen refresh rate. You could share your CPU usage as it might indicate the problem, is it too much work or too much sleep and wait ? To do that, use Process Explorer from Sysinternals, then double click on your application, in that properties window, take screenshot of two tabs, and another screenshot for the following tabs after some time passed like 1 minute or more: Threads Performance Graph These tabs might help identifying strange or wrong behavior or at least will give an insight of the performance in overall.
  9. OK, But evidently your application usage of Sleep is showing a problem if understanding its impact, see, Sleep(1) aka sleep for 1 millisecond by default will be 1000/64=15.625 ms, limiting that specific path of code to 64 time per second, this will affect UI greatly, so : 1) Search for every Sleep call in your project from the main thread and remove them, don't use Sleep in main thread not for 1 or even 0 ms, they makes no sense, for background thread it is understandable and useful, but again if the main thread will wait for background thread to finish rendering an animation to paint it then again UI will behave as you described. 2) In my life i may be have used ApplicationIdle few times that can be counted on hand, mostly were to logout or clean up and close stuff or finish opened procedure to not causing blocking something online, but i have removed tens of these handlers from projects that are not mine, due the abuse and misunderstanding of usage, ApplicationIdle is healthy way to see that your UI is responsive the more is called the better, and never use it for something take long time, if needed then start background thread to do it. 3) Your animation most likely is the cause, this is my guess, a thread is doing something while main thread is waiting on it to paint, that is wrong approach, let the thread render (prepare what ever), on other hand use a timer, simple timer with adequate interval to see if that thread or the animation is ready to be painted then draw/paint it, and exit, don't use interval higher than 60 per second, as this is useless and waste of time, on other hand try to centralize all your animations with one timer and one class that do the draw/paint, you don't need every animated button to use 60 message per second, right ? because this will starve UI from handing message and produce the mentioned behavior.
  10. You are calling Sleep(interval) in GameScreenMenu.TGameScreenMenu.ApplicationIdle , this interval either too big or being called too many times behaving like deadlock. the problem is not exactly there, but in some sort of combination with waiting on some event or value from the TGameBaseMenuScreen, as this one is in DoLevelSelect is executing ShowModal . So your ShowModal is implemented in the base class while you ApplicationIdle is in the inherited one, now make sure you are not checking on any Form.Handle as it might be recreated in other words, your ShowModal form might be not visible or lost track of some of its internal fields where your Idle handler is waiting on it. Suggestion : 1) redo or completely remove that Idle handler, by redo i mean re-code it in defensive way assuming you can't trust any locally stored values and check them at runtime every time you evaluating something namely and most critically before calling a Sleep, 2) Why on earth you need to call on Sleep to begin with ? if you step back to look at what is going on, OnIdle is executed when the application is Idle and no work to, but you are introducing a work for it by calling Sleep !!
  11. I have no idea why i wrote "doesn't".
  12. I used ApiMonitor to track this behavior, the result of all clipboard functions called for MMC.exe : One function in particular is the culprit so i tested it and found SetClipboardViewer(0); // invalid handle here This will trigger sending WM_CLIPBOARDUPDATE to all registered handlers, mmc is calling it, i think many of these system administration tools will call it too. Save the clipboard content or part of it and compare for changes on every WM_CLIPBOARDUPDATE.
  13. Kas Ob.


    Most likely you can, but just for editing files, it is easier to use Notepad++ than Delphi to edit JavaScript and HTML, from https://developer.kaiostech.com/
  14. Kas Ob.

    CTRL+C to a console app vs. TerminateProcess(..)

    You nicely summarized the good, the bad and the ugly in spawning console processes. My thoughts here: 1) The role of thumb for console application to be terminated at any time, and these signals or ControlEvent are not to reliable to be depends on, yet there is some cases where they are needed to not lose some job or as you named it gracefully terminate. 2) as for application you pointed to wstcp, i don't see any such event handler in the source, (may be i missed something) but you can check for your self https://rust-cli.github.io/book/in-depth/signals.html 3) As for your own processes then i suggest to try different IPC than standard console pipe, like Memory Sharing, it will give you better speed, like you can use background threads to wait on events or simply let the spawned processed write to the named shared memory passed to them in a command line and the mother process will check with intervals and read ... remember there nothing prevent a spawned from allocating shared memory too for lets say specific temporary file or stream of data and put the name in predefined table which also shared but from the owner process and passed to the child... anyway there is many approaches to handle this, and they all will remove the need the dependency on events like CTRL+C 4) if you not sure if the 3rd party process does require graceful termination then don't use TerminateProcess, make sure all your other process handle such event and either refuse to close or terminate too, but again you need to tell them first through some IPC that an event is coming and should be ignored. Again for that "WebSocket to TCP proxy" it is fine to use terminate process. All the concerning points in ExitProcess are for a process calling ExitProcess itself and it is recommending to switch to TerminateProcess for the case where the same process is not sure if it has a thread locking a detaching DLL callback function, so TerminateThread is safer and should be in mind when designing an application. Also notice my suggestion above for using shared memory and wait can be the worst because of if an application is built to wait on some value in memory shared then TerminateProcess will put the waiting process in deadlock, hence you should a thread to poll the value and not wait, or wait on an event, created by the child process hence the Exit/Terminate will signal it.