Jump to content
Willicious

Decrement a value by 1 each time a function is called

Recommended Posts

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 by Willicious

Share this post


Link to post
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 by Stefan Glienke
  • Like 3

Share this post


Link to post

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
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
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...

  • Like 1

Share this post


Link to post
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 by Willicious

Share this post


Link to post

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 by programmerdelphi2k

Share this post


Link to post

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 by programmerdelphi2k

Share this post


Link to post
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

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×