/**
   * This is called every frame in BaseGame.start()
   *
   * @param interpolation unused in this implementation
   * @see AbstractGame#update(float interpolation)
   */
  protected final void update(float interpolation) {
    // Recalculate the framerate.
    timer.update();
    tpf = timer.getTimePerFrame();

    // Update the current game state.
    GameStateManager.getInstance().update(tpf);
  }
  /*
   * (non-Javadoc)
   *
   * @see java.lang.Thread#run()
   */
  @Override
  public void run() {
    logger.debug("UpdateThread started.");
    lasttick = timer.getTimeInSeconds();
    float currentTime = 0.0f;
    while (keepRunning) {
      lock.lock();
      currentTime = timer.getTimeInSeconds();
      float dt = (float) (currentTime - (lasttick + offset));
      offset = 0;
      GameTaskQueueManager.getManager().getQueue(GameTaskQueue.UPDATE).execute();
      sceneData.getRoomNode().updateGeometricState(dt, true);
      sceneData.getRootNode().updateGeometricState(dt, true);
      performCameraMotion();
      GameStateManager.getInstance().update(dt);
      if (!isPaused()) {
        sceneData.getCollisionHandler().update(dt);
        sceneData.getPhysicsSpace().update(dt);
      }
      TextOverlayManager.getInstance().update(dt);
      float timePassed = currentTime - lasttick;
      synchronized (repeatedActions) {
        for (RepeatedUpdateAction action : repeatedActions) {
          action.doUpdate(timePassed);
        }
      }

      if (sceneData.getRootNode() != null) {
        // TODO: should probably go away
        sceneData.getRootNode().updateRenderState();
      }
      lasttick = currentTime;
      fieldService.checkFields();
      lock.unlock();
      try {
        sleep(10);
      } catch (InterruptedException e) {
        // we can ignore this buddy
      }
      if (isPaused()) {
        offset += 0.001f;
      }
    }
    logger.debug("UpdateThread stopped.");
  }
 /**
  * @param rootNode root of the scene to update
  * @param physicsSpace associated physics space
  * @param update update queue to use
  * @param fieldService current fieldservice
  */
 public UpdateThread(
     ReentrantLock lock,
     SceneData sceneData,
     List<RepeatedUpdateAction> repeatedActions,
     FieldService fieldService,
     CameraService cameraService) {
   logger.debug("New UpdateThread instantiated.");
   timer = Timer.getTimer();
   this.lock = lock;
   this.setName("UpdateThread");
   this.sceneData = sceneData;
   this.repeatedActions = Collections.synchronizedList(repeatedActions);
   this.fieldService = fieldService;
   this.cameraService = cameraService;
 }
  /**
   * Creates display, sets up camera, and binds keys. Called in BaseGame.start() directly after the
   * dialog box.
   *
   * @see AbstractGame#initSystem()
   */
  protected final void initSystem() {
    try {
      /** Get a DisplaySystem acording to the renderer selected in the startup box. */
      display = DisplaySystem.getDisplaySystem(settings.getRenderer());
      /** Create a window with the startup box's information. */
      display.createWindow(
          settings.getWidth(),
          settings.getHeight(),
          settings.getDepth(),
          settings.getFrequency(),
          settings.isFullscreen());
      /**
       * Create a camera specific to the DisplaySystem that works with the display's width and
       * height
       */
    } catch (JmeException e) {
      /** If the displaysystem can't be initialized correctly, exit instantly. */
      logger.log(Level.SEVERE, "Could not create displaySystem", e);
      System.exit(1);
    }

    /** Get a high resolution timer for FPS updates. */
    timer = Timer.getTimer();
  }