Willicious 8 Posted May 11, 2023 (edited) I need to decrement a value by 1 each time a function is called. Here's what I have so far: function TGame.HandleState: Boolean; begin Result := True; Dec(MyValue); end; Note that MyValue is a private component of the class in which this function lives, and is used by various other functions and procedures throughout the unit, so it cannot be defined within this function. The above function does indeed decrement MyValue by 1, but it does so repeatedly when the function is called only once. I need it to only decrement by 1 each time the function is called. I've tried Dec(MyValue, 1); but that just behaves the same way (i.e. repeatedly decreasing the value from a single call of the function). I also tried this: function TGame.HandleState: Boolean; var i: Integer; begin Result := True; i := MyValue -1; if i = MyValue then Dec(MyValue); end; But, that obviously doesn't work because i will never = MyValue if it's set to MyValue -1; Any ideas? Edited May 11, 2023 by Willicious Share this post Link to post
Stefan Glienke 2002 Posted May 11, 2023 (edited) 7 minutes ago, Willicious said: The above function does indeed decrement MyValue by 1, but it does so repeatedly when the function is called only once. Cannot be - if it's decremented by more than 1 then because the method was called more than once, simple as that. If the method is being called from multiple threads you need to use AtomicDecrement though. If you don't know from where the method is being called unexpectedly, use a data breakpoint on MyValue and the debugger will stop as soon as its being modified Edited May 11, 2023 by Stefan Glienke 3 Share this post Link to post
Uwe Raabe 2057 Posted May 11, 2023 Could it be that the function is called in the debugger evaluator? If so, it should work as expected in the release version. Share this post Link to post
Willicious 8 Posted May 11, 2023 26 minutes ago, Stefan Glienke said: Cannot be - if it's decremented by more than 1 then because the method was called more than once, simple as that. If the method is being called from multiple threads you need to use AtomicDecrement though. Yes, I think the function is repeatedly "called" or "active" whilst the game is handling that particular state. So, each frame, the count is decremented by 1. That's the answer. I'm not really sure what the way around this is. 9 minutes ago, Uwe Raabe said: Could it be that the function is called in the debugger evaluator? If so, it should work as expected in the release version. Good suggestion, and it was worth a try, but sadly even the release version doesn't correct the behaviour. Share this post Link to post
Sherlock 663 Posted May 11, 2023 23 minutes ago, Willicious said: That's the answer. I'm not really sure what the way around this is. Use a different event. Or only count down after a significant amount of frames... 1 Share this post Link to post
Willicious 8 Posted May 11, 2023 (edited) 6 minutes ago, Sherlock said: Use a different event. Or only count down after a significant amount of frames... Yes, this was my eventual solution! function TGame.HandleState: Boolean; begin Result := True; if Frame = 1 then Dec(MyValue); end Luckily, the animation loops from frames 8-16 once the state is entered, so all I needed to do was call Dec(MyValue); on the first frame. Pending testing, I think this one is resolved! Edited May 11, 2023 by Willicious Share this post Link to post
programmerdelphi2k 237 Posted May 11, 2023 (edited) well, if you needs know "how much" and dont want use breakpoints, then try "log it" (send all info when your function was accessed, later, look it) using a "file" as your target... or if in IDE, using any "listening" to debug, like Konopka KSVC (Raize components) suite or same you can send the message to MSWindows logger, in real-time! Edited May 11, 2023 by programmerdelphi2k Share this post Link to post
programmerdelphi2k 237 Posted May 11, 2023 (edited) here my sample for tests uses uMyLogger; procedure TForm1.BtnAddAnErrorOnMSWindowsEventLogClick(Sender: TObject); var i: integer; begin randomize; i := random($FFFFFFF); // TMyLoggerOnMSWindowsEventLogger.CustomLog('meu app: ' + i.ToString, 'meu error: ' + i.ToString); end; now, look in MS Events Viewer Edited May 11, 2023 by programmerdelphi2k Share this post Link to post
David Heffernan 2345 Posted May 11, 2023 18 minutes ago, programmerdelphi2k said: randomize; i := random($FFFFFFF); It's something of an anti-pattern to call Randomize more than once in the lifetime of a process. Why do you have this call here? Share this post Link to post
programmerdelphi2k 237 Posted May 11, 2023 this was a long time ago... I just found in my backup... just use Konopka CodeSite, maybe have some pattern 😂 uses CodeSiteLogging; procedure TForm1.Button1Click(Sender: TObject); begin CodeSite.Send('hello'); end; Share this post Link to post