* The timer keeps calculating the passed time while it's running, * calling the respective action handler whenever the set interval passes. * @param state State that the action handler belongs to. * @param surface Surface that the action handler belongs to. */
| 108 | * @param surface Surface that the action handler belongs to. |
| 109 | */ |
| 110 | void Timer::think(State* state, Surface* surface) |
| 111 | { |
| 112 | Sint64 now = slowTick(); // must be signed to permit negative numbers |
| 113 | Game *game = state ? state->_game : 0; // this is used to make sure we stop calling *_state on *state in the loop once *state has been popped and deallocated |
| 114 | //assert(!game || game->isState(state)); |
| 115 | |
| 116 | if (_running) |
| 117 | { |
| 118 | if ((now - _frameSkipStart) >= _interval) |
| 119 | { |
| 120 | for (int i = 0; i <= maxFrameSkip && isRunning() && (now - _frameSkipStart) >= _interval; ++i) |
| 121 | { |
| 122 | if (state != 0 && _state != 0) |
| 123 | { |
| 124 | (state->*_state)(); |
| 125 | } |
| 126 | _frameSkipStart += _interval; |
| 127 | // breaking here after one iteration effectively returns this function to its old functionality: |
| 128 | if (!game || !_frameSkipping || !game->isState(state)) break; // if game isn't set, we can't verify *state |
| 129 | } |
| 130 | |
| 131 | if (_running && surface != 0 && _surface != 0) |
| 132 | { |
| 133 | (surface->*_surface)(); |
| 134 | } |
| 135 | _start = slowTick(); |
| 136 | if (_start > _frameSkipStart) _frameSkipStart = _start; // don't play animations in ffwd to catch up :P |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | /** |
| 142 | * Changes the timer's interval to a new value. |