private void registerButtonBinds(
      InputSystem inputSystem, ModuleEnvironment environment, Iterable<Class<?>> classes) {
    for (Class<?> registerBindClass : classes) {
      RegisterBindButton info = registerBindClass.getAnnotation(RegisterBindButton.class);
      SimpleUri bindUri =
          new SimpleUri(environment.getModuleProviding(registerBindClass), info.id());
      if (BindButtonEvent.class.isAssignableFrom(registerBindClass)) {
        try {
          BindableButton bindButton =
              inputSystem.registerBindButton(
                  bindUri, info.description(), (BindButtonEvent) registerBindClass.newInstance());
          bindButton.setMode(info.mode());
          bindButton.setRepeating(info.repeating());

          for (Input input : getBinds(bindUri)) {
            if (input != null) {
              inputSystem.linkBindButtonToInput(input, bindUri);
            }
          }

          logger.debug("Registered button bind: {}", bindUri);
        } catch (InstantiationException | IllegalAccessException e) {
          logger.error("Failed to register button bind \"{}\"", e);
        }
      } else {
        logger.error(
            "Failed to register button bind \"{}\", does not extend BindButtonEvent", bindUri);
      }
    }
  }
 private void switchState(GameState newState) {
   if (currentState != null) {
     currentState.dispose();
   }
   currentState = newState;
   LoggingContext.setGameState(newState);
   newState.init(this);
   for (StateChangeSubscriber subscriber : stateChangeSubscribers) {
     subscriber.onStateChange();
   }
   // drain input queues
   InputSystem inputSystem = rootContext.get(InputSystem.class);
   inputSystem.getMouseDevice().getInputQueue();
   inputSystem.getKeyboard().getInputQueue();
 }
 public void applyBinds(InputSystem inputSystem, ModuleManager moduleManager) {
   inputSystem.clearBinds();
   ModuleEnvironment env = moduleManager.getEnvironment();
   registerButtonBinds(inputSystem, env, env.getTypesAnnotatedWith(RegisterBindButton.class));
   registerAxisBinds(inputSystem, env, env.getTypesAnnotatedWith(RegisterBindAxis.class));
   registerRealAxisBinds(inputSystem, env, env.getTypesAnnotatedWith(RegisterRealBindAxis.class));
 }
 private void registerAxisBinds(
     InputSystem inputSystem, ModuleEnvironment environment, Iterable<Class<?>> classes) {
   for (Class<?> registerBindClass : classes) {
     RegisterBindAxis info = registerBindClass.getAnnotation(RegisterBindAxis.class);
     Name moduleId = environment.getModuleProviding(registerBindClass);
     SimpleUri id = new SimpleUri(moduleId, info.id());
     if (BindAxisEvent.class.isAssignableFrom(registerBindClass)) {
       BindableButton positiveButton =
           inputSystem.getBindButton(new SimpleUri(info.positiveButton()));
       BindableButton negativeButton =
           inputSystem.getBindButton(new SimpleUri(info.negativeButton()));
       if (positiveButton == null) {
         logger.warn(
             "Failed to register axis \"{}\", missing positive button \"{}\"",
             id,
             info.positiveButton());
         continue;
       }
       if (negativeButton == null) {
         logger.warn(
             "Failed to register axis \"{}\", missing negative button \"{}\"",
             id,
             info.negativeButton());
         continue;
       }
       try {
         BindableAxis bindAxis =
             inputSystem.registerBindAxis(
                 id.toString(),
                 (BindAxisEvent) registerBindClass.newInstance(),
                 positiveButton,
                 negativeButton);
         bindAxis.setSendEventMode(info.eventMode());
         logger.debug("Registered axis bind: {}", id);
       } catch (InstantiationException | IllegalAccessException e) {
         logger.error("Failed to register axis bind \"{}\"", id, e);
       }
     } else {
       logger.error("Failed to register axis bind \"{}\", does not extend BindAxisEvent", id);
     }
   }
 }
 private void registerRealAxisBinds(
     InputSystem inputSystem, ModuleEnvironment environment, Iterable<Class<?>> classes) {
   for (Class<?> registerBindClass : classes) {
     RegisterRealBindAxis info = registerBindClass.getAnnotation(RegisterRealBindAxis.class);
     Name moduleId = environment.getModuleProviding(registerBindClass);
     SimpleUri id = new SimpleUri(moduleId, info.id());
     if (BindAxisEvent.class.isAssignableFrom(registerBindClass)) {
       try {
         BindAxisEvent instance = (BindAxisEvent) registerBindClass.newInstance();
         BindableAxis bindAxis = inputSystem.registerRealBindAxis(id.toString(), instance);
         bindAxis.setSendEventMode(info.eventMode());
         for (Input input : getBinds(id)) {
           inputSystem.linkAxisToInput(input, id);
         }
         logger.debug("Registered axis bind: {}", id);
       } catch (InstantiationException | IllegalAccessException e) {
         logger.error("Failed to register axis bind \"{}\"", id, e);
       }
     } else {
       logger.error("Failed to register axis bind \"{}\", does not extend BindAxisEvent", id);
     }
   }
 }