Download

[SOLVED] How to reset timer? Set with same handle doesn't work?

Hello, can’t seem to reset a timer.
Would you please check code below, and tell me if this approach simply won’t work >(
Thank you!

Can I make an FTimerHandle this way?
Supposing the problem isn’t in saving the handle, can I reset timer by handle?


void AChar::Affected (const EState Key) {

  FTimerHandle Timer; // make a handle ?
  // read Stat, Value, Duration etc from table

  // supposing the problem isn't here -----------
  if (Effects.Add(Key, Timer)) { /* apply effect */ }
  // Effects.Add checks do we already have it, by Key
  // if yes, return false and modify InTimer by ref&
  // if no, return true and save InKey and InTimer internally

  // ---------- should this work ? or is my princess in another castle...
  if (Duration > 0.f) {
    auto Call = FTimerDelegate::CreateLambda( /* remove effect */ );
    GetWorldTimerManager().SetTimer(Timer, Call, Duration, false);
    // PROBLEM: doesn't reset the timer, always sets a new one? :(
  }

}

I want to set the timer, save its handle, and if same effect is added, restart the timer by handle.
Instead, I’m getting added only once (so we know that check works), but the effect is removed multiple times.
Aka, each use adds a new timer until effect removal, instead of resetting the old one.

Thanks a bunch!


SOLUTION

SetTimer with the same handle indeed does reset the timer as expected.
The problem was that just by declaring an FTimerHandle Timer; you generate an invalid handle (basically an uint64 0).
The handle is only filled once it was used by SetTimer, therefore you need to save it after the timer was set.



// bad
FTimerHandle Timer;
MyTimers* = Timer;
SetTimer(Timer, ...);

// good
FTimerHandle Timer;
SetTimer(Timer, ...);
MyTimers* = Timer;


Cheers

put this in your .h file.



FTimerHandle Timer;

This will clear the timer so you can use it again.


if (GetWorldTimerManager().IsTimerActive(Timer))
GetWorldTimerManager()).ClearTimer(Timer);

When you need to restart it just use your SetTimer line.

Gameplay Timers

Thank you for your responses.

@gamepainters ok, I’ma try that. Was thinking no - because ClearTimer has the following to say:

  • Invalidates the timer handle as it should no longer be used.
    and calls
    /** Explicitly clear handle */ void Invalidate() { Handle = 0; }

I’m a try. I guess if it works for you, it’ll work for me.

@STRiFE.x ? that’s a link to the docs, yes. Yes, I’ve read it. Could you be a bit more precise :slight_smile: there’s nothing on there regarding restarting. Maybe I missed it. Could you pls point me?
There’s this bit
“Calling SetTimer with an existing timer handle will clear the timer referenced by that timer handle and replace it with a new one.”
but that’s what I was doing, no?

Cheers

Your


FTimerHandle Timer

is a local variable to your function, each time the function is called it is a completely new variable, not the same as the last time you accessed it. The key point here is to change it to be a class variable as gamepainters pointed. This is not about how the TimerHandle works, this is just how C++ works.

Ok I think I got it. It’s the SetTimer that fills the handle, not just constructing it. (It is constructed with an invalid handle of uint64 0).

@_brunocoimbra thanks for your response. I was saving the handle in a sub-struct by ref (during Effects.Add), but the problem was I was saving it before filling it with SetTimer, therefore always saving an invalid handle.

If the handle is in the .h file, When you clear the timer. You are stopping the timer it self, not destroying the handle. So it is ready for use thru out the file anytime you need it.

The handle will always be ready to be used in that class or classes (depending on how you define it > public: protected: private:). I my self have been setting mine up private: So they are only used in the class i defined the handle in.

I did set one up on public as i needed another class to run the clear timer on it. So i had to use public on it.