Listing 2

1  long fractions = 0L;

2  long overSleepTime = 0L;

3  int noDelays = 0;

4  animating = true;

5  StopWatch stopWatch

       = StopWatchSource.getStopWatch();

6  stopWatch.start();

7

8  while(animating) {

9

10   // Update the game state

11   listener.updateModel();

12

13   // Obtain a graphics context to the

14   // back buffer and render the frame

15   Graphics g = bufferStrategy

         .getDrawGraphics();

16

17   if (bufferStrategy.contentsLost())

18     clearCount = (isPageFlipping)

           ? 2 : 1;

19   else {

20     boolean isBufferCleared = false;

21     if (clearCount > 0) {

22       clearCount--;

23       isBufferCleared = true;

24     }

25     listener.render(g,

          isBufferCleared, bufferIndex);

26     bufferStrategy.show();

27     if (isPageFlipping)

28       bufferIndex =

             (bufferIndex == 0) ? 1 : 0;

29   }

30   g.dispose();

31

32   // Compute the time remaining in

33   // the frame period

33   long sleepTime = PERIOD

       - stopWatch.stop()-overSleepTime;

34

35   // If there is time remaining,

36   // sleep it away

37   stopWatch.start();

38   if (sleepTime >= 0L) {

39     Thread.sleep(

           sleepTime / 1000000L);

40     overSleepTime = stopWatch.stop()

           - sleepTime;

41     stopWatch.start();

42   } else {

43

44     // Otherwise aggregate the excess

45     fractions -= sleepTime;

46     overSleepTime = 0L;

47

48     if (++noDelays

           >= NO_DELAYS_PER_YIELD) {

49       Thread.yield();

50       noDelays = 0;

51     }

52   }

53

54   // While excess aggregate exceeds

55   // frame period, update the model

56   int skips = 0;

57   while(fractions > PERIOD

         && ++skips < maxFrameSkips) {

58     fractions -= PERIOD;

59     listener.updateModel();

60   }

61   while(fractions > PERIOD)

62     fractions -= PERIOD;

63   }

64 }