Jump to content

dormky

Members
  • Content Count

    150
  • Joined

  • Last visited

Everything posted by dormky

  1. That's not a problem here, the code called by the timer is "fire and forget".
  2. Except that I'm putting the timer in a thread for a reason. If it's on the main thread, it runs the risk of getting delay by other work (namely, heavy drawing). If the timer is delayed, the event is delayed too.
  3. Well, if someone's already made the relevant code to create a timer there's no reason to write one myself.
  4. Well, it seems that no matter what I do, the timer's callback is always executed in the main thread. Anyone have a recommendation for a TTimer equivalent that has its callback executed in the thread it was created in ?
  5. > You need to run your timer related code within the Execute method I would need to have the timer callback set a flag that a loop in the Execute would check ? That seems exceedingly strange. I just want a timer that exists and executes in a thread other then the main thread. The timer's interval is subject to change, and is in a class whose logic should be able to run on both main and other threads, hence why I haven't put the logic in the Execute method directly.
  6. It feels so wasteful to have a method running with something like "while not Terminated do Sleep(10);". Is there not a better way of having the thread idle ?
  7. I've tried to install the https://github.com/CHERTS/newac component, but while it shows up in the Components list and the palette contains all the elements it should, dragging and dropping an element onto a form automatically adds the relevant units to the uses list... but Delphi can't resolve them. What could I have done wrong in the installation for this to happen ? I opened the .dpk file, right-clicked on the .bpl group and clicked Compile, then Install. Everything seemed to be fine until I actually tried it. I tried installing with both the NewAC file and the NewAC_Rio file (I'm on Delphi 10.3.2).
  8. I need to make a metronome. For this purpose I've been trying to use TTimer, but it seems that for every call, it spawns a new thread. How can I prevent this and make it run in the program's main thread ? The problem is that I'm calling a windows API asynchronously, which means the timer's thread ends before the Windows call completes.
  9. dormky

    How can I make TTimer run in the main tread ?

    This is the VCL subforum 😕 And this is async, so disabling the timer in-between would have no effect. And this is a metronome, so I need to be as exact as possible.
  10. dormky

    How can I make TTimer run in the main tread ?

    It breaks down when you go above 1000ms interval, try it with 500ms. You can even see the "Thread start" logs still going after stopping the timer.
  11. dormky

    How can I make TTimer run in the main tread ?

    Ah, nevermind ! It seems that it's the Windows API call making this thread. Now why does calling PlaySound not work when it's called from a TTimer callback, I have no idea.
  12. dormky

    How can I make TTimer run in the main tread ?

    Every call prints "Thread ID start" and "Thread ID Exit" to the debug log.
  13. I have a very, very large record that may cause memory issues for the stack if I use multiples instances of it in a procedure. I'd like to force delphi to allocate it on the heap so this doesn't happen. I need it to stay a record, it can't be a class. I have no problem with doing a bit of manual work in the procedure to get this, it doesn't have to be something baked in the framework and invisible to me as a dev. I'm sure this is possible in a simple way, I just can't find it through Google... Thanks !
  14. Believe me I would love to move away from this pattern, but unfortunately we have decades-old data stored like this, with the whole rest of the program built around it. It's too late ; the only thing I can do now is make it as safe and as readable as possible for future generations, lol.
  15. TBloodyTColor1 = record aVar: smallint; aColor: TColor; end; TBloodyTColor2 = record aVar: smallint; aColor: TColor; aVar2: smallint; end; TBloodyTColor3 = record aVar: smallint; aVar2: smallint; aVar3: smallint; end; The results of "sizeof" for these 3 records are : TBloodyTColor1 : 8 TBloodyTColor2 : 12 TBloodyTColor3 : 6 The size of a TColor is 4 bytes, a smallint is 2 bytes. TBloodyTColor1 & 3 should take the same amount of memory, yet when using TColor 2 bytes are added. I believed this was for memory alignment purposes, but we can see that's not the case by looking at TBloodyTColor2, where 4 bytes are added (if I had to assume, they're probably 2 bytes before & after the TColor). This is incredibly annoying. It's basically impossible to predict how much space a record is going to take ! Looking at the definition of TColor, TColor = -$7FFFFFFF-1..$7FFFFFFF; indicates that the 7 here might be at fault ? Just looking for some insight on the subject, because this makes static analysis incredibly difficult for really no good reason...
  16. Unfortunately, no. Most of said records are just wrapping underlying anonymous arrays and records, and there's no RTTI generated for those (I need to get the actual name of the field so a human can read the comparison). A field like "array [0..1] of record X, Y: smallint; end;" doesn't have RTTI, and there's a lot of those. And for your entertainment, things are actually worse than this because anytime one of these arrays needs to be grown for a change in the program, we need to keep the old version of the record so we can read the old file, and a new one with the change. And all the fields need to be manually copied over, there's tens of thousands of lines of "current.field := V22.field" :') So yeah. I don't know who went with this model of configuration storage, but if I get my hands on them they're in trouble, to say the least. Edit : I could take out the anonymous stuff and declare it properly, but that would make an even bigger mess of things, add a lot more versioning like shown above, etc... All to be able to compare the god damned configs. So I want to evade doing that if possible, such a big number of changes would have no chance of me not making a mistake somewhere in my copy-pasting, and of course we have 0 tests.
  17. Ah, thank you for the explanation and link, this is the info I was looking for ! @David Heffernan I'm looking into this because we have config files that are just memory dumps of records. I need to be able to meaningfully compare and manipulate those files. There is A LOT of them and doing so manually would be hopeless.
  18. @Alexander Sviridenkov Perfect, thank you very much !
  19. That does simple to be the simple thing I was looking for, thanks 🙂 How do I free this though ?
  20. How do I disable code completion ? It keeps giving me unit names, which is possibly the worse thing it could ever propose. I'm on Dlephi 10.3 and everything is already disabled, but the autocompletion still happens. Thanks !
  21. dormky

    Disabling autocompletion

    Nevermind, just discovered that the autocompletion box had small buttons next to it and one of those is the settings for code completion.
  22. I'm trying to use TRttiField.SetValue with a generic type. TTestClass = class(TObject) testValue: Integer; end; function testProc<T>() : TArray<T>; // // Code to get the relevant field... // field.SetValue(Result[i], TValue.From<Integer>(47)); // Fails : E2010 Incompatible types: 'Pointer' and 'T' end; If I try to make a PByte(Result) myself, this also fails with an incompatible typecast. All a want is the address of my field so I can write a value there. Thanks ! Edit : Okay, found an horrendous solution : procedure makeCopy(var dest; value: Variant; field: TRttiField); begin field.SetValue(Pointer(dest), TValue.FromVariant(value)); end; This works for my simple field, probably won't for more complex stuff. You end up with an additional function call for every SetValue just to get around the compiler, but alas...
  23. That's totally correct, but the fact that I can't grab a Pointer directly but there's a simple workaround shows that this is a (probably willful) limitation of the compiler.
  24. I have some code doing imports and updating the UI as it goes. When running with the debugger attached, everything goes fine. But running the exe itself (the exact same exe that was just compiled for the debugger run), the UI freezes. What's weird is that it only starts doing this after a few seconds, and not in the same place everytime either. What's going on here ? Has anyone encountered this before ? I can see the logs as the exe runs (with its UI frozen), so I know the code is still working fine. When I say "frozen", I mean that Windows whites it out and if you click on it, it will say that the program isn't answering.
  25. dormky

    Program freezes when not linked to debugger

    The main thread is not frozen, the data is still being imported. It's just the UI that freezes after a few seconds. If the lack of call to Application.ProcessMessages() was at fault, the freeze would be immediate, but it's not, I can see rows getting added in the UI... until I can't because of the freeze. @Kas Ob.It's not done in a background thread. I would have mentioned it if it was. Same thing with the running time, it's the same in both instances.
×