> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dairy.foundation/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage

The basics:

<CodeGroup>
  ```java Java theme={null}
  // Pasteurized offers advanced versions of the gamepads
  Pasteurized.gamepad1();
  Pasteurized.gamepad2();

  // buttons on the gamepads are represented by EnhancedBooleanSuppliers
  EnhancedBooleanSupplier enhancedBooleanSupplier = Pasteurized.gamepad1().a();

  enhancedBooleanSupplier.state(); // current state
  enhancedBooleanSupplier.onTrue(); // a rising edge detector
  enhancedBooleanSupplier.onFalse(); // a falling edge detector
  enhancedBooleanSupplier.toggleTrue(); // a toggle that gets changed whenever a rising edge is detected
  enhancedBooleanSupplier.toggleFalse(); // a toggle that gets changed whenever a falling edge is detected

  // sticks and triggers are represented via EnhancedNumberSuppliers
  EnhancedDoubleSupplier enhancedNumberSupplier = Pasteurized.gamepad1().leftStickY();

  // the value of the stick
  enhancedNumberSupplier.state();

  // EnhancedNumberSuppliers also interact well with building complex EnhancedBooleanSuppliers from ranges
  EnhancedBooleanSupplier rangeBasedCondition = enhancedNumberSupplier.conditionalBindState()
  		.greaterThan(-0.5)
  		.lessThan(0.5)
  		.bind();

  // this system is fairly intuitive, and works best if you list numbers from smallest to largest,
  // or in pairs e.g.:

  EnhancedBooleanSupplier complexRangeBasedCondition = enhancedNumberSupplier.conditionalBindState()
  		.greaterThan(0.0)
  		.lessThan(10.0)
  		.greaterThanEqualTo(1.0)
  		.lessThanEqualTo(1000.0)
  		.bind();

  // note: the Pasteurized gamepads have remaps for all gamepad buttons and inputs, the inputs that are shared across the different gamepad types
  // but share a name (i.e. cross on a ps4 controller and a on a logitech or x-box controller) are linked together on the Pasteurized gamepad
  ```

  ```kt Kotlin theme={null}
  // Pasteurized offers advanced versions of the gamepads
  Pasteurized.gamepad1
  Pasteurized.gamepad2

  // buttons on the gamepads are represented by EnhancedBooleanSuppliers
  var enhancedBooleanSupplier = Pasteurized.gamepad1.a

  enhancedBooleanSupplier.state // current state
  enhancedBooleanSupplier.onTrue // a rising edge detector
  enhancedBooleanSupplier.onFalse // a falling edge detector
  enhancedBooleanSupplier.toggleTrue // a toggle that gets changed whenever a rising edge is detected
  enhancedBooleanSupplier.toggleFalse // a toggle that gets changed whenever a falling edge is detected

  // sticks and triggers are represented via EnhancedNumberSuppliers
  val enhancedNumberSupplier = Pasteurized.gamepad1.leftStickY

  // the value of the stick
  enhancedNumberSupplier.state

  // EnhancedNumberSuppliers also interact well with building complex EnhancedBooleanSuppliers from ranges
  val rangeBasedCondition = enhancedNumberSupplier.conditionalBindState()
  		.greaterThan(-0.5)
  		.lessThan(0.5)
  		.bind()

  // this system is fairly intuitive, and works best if you list numbers from smallest to largest,
  // or in pairs e.g.:

  val complexRangeBasedCondition = enhancedNumberSupplier.conditionalBindState()
  		.greaterThan(0.0)
  		.lessThan(10.0)
  		.greaterThanEqualTo(1.0)
  		.lessThanEqualTo(1000.0)
  		.bind()

  // note: the Pasteurized gamepads have remaps for all gamepad buttons and inputs, the inputs that are shared across the different gamepad types
  // but share a name (i.e. cross on a ps4 controller and a on a logitech or x-box controller) are linked together on the Pasteurized gamepad
  ```
</CodeGroup>

Pasteurized uses
[EnhancedBooleanSuppliers](/Core/enhancedsuppliers/enhanced_boolean_supplier)
and
[EnhancedNumericSuppliers](/Core/enhancedsuppliers/enhanced_numeric_supplier).

Go take a read for further usage of those

Modifying the global gamepads:

<CodeGroup>
  ```java Java theme={null}
  // you can also reassign the buttons on the gamepads themselves, if you wish to make a change more global
  Pasteurized.gamepad2().a(
  		Pasteurized.gamepad1().a().or(Pasteurized.gamepad2().a())
  );
  Pasteurized.gamepad1().a(Pasteurized.gamepad2().a());
  // now either the driver or the operator can trigger this condition!

  // or, you can build a gamepad yourself, (see below for more on this) and
  // re-assign the whole gamepad!
  // new SDKGamepad() will build a default gamepad from an sdk gamepad
  // so this would reset gamepad1
  Pasteurized.gamepad1(new SDKGamepad(gamepad1));

  // or we could merge the two together
  Pasteruized.gamepad2(Pasteruized.gamepad1());
  ```

  ```kt Kotlin theme={null}
  // you can also reassign the buttons on the gamepads themselves, if you wish to make a change more global
  Pasteurized.gamepad2.a = Pasteurized.gamepad1.a or Pasteurized.gamepad2.a
  Pasteurized.gamepad1.a = Pasteurized.gamepad2.a
  // now either the driver or the operator can trigger this condition!

  // or, you can build a gamepad yourself, (see below for more on this) and
  // re-assign the whole gamepad!
  // new SDKGamepad() will build a default gamepad from an sdk gamepad
  // so this would reset gamepad1
  Pasteurized.gamepad1 = SDKGamepad(gamepad1)

  // or we could merge the two together
  Pasteruized.gamepad2 = Pasteruized.gamepad1
  ```
</CodeGroup>

Layering:

<CodeGroup>
  ```java Java theme={null}
  // we'll use this enum
  enum Layers {
  	TELEOP,
  	ENDGAME
  }

  // WARNING: once you add a gamepad to a layering system, it will cease to function normally
  // when a gamepad is put into a layering system, it is modified to go to being 'at-rest' when its not the active layer for the system
  // 'at-rest' gamepads have 0 for all axis, and false for all buttons

  // If you want to get more advanced, you can use a layering system to control the layers of your gamepad
  // gamepads on inactive layers will immediately go to an 'at-rest' state, layering systems achieve this by modifying all gamepads given to it
  SDKGamepad teleopGamepad = new SDKGamepad(gamepad1);

  // WARNING: if your layering system is not very stable, you will need to be careful, as a layered gamepad will crash if it can't find a gamepad for the current layer
  SDKGamepad endgameGamepad = new SDKGamepad(gamepad1);

  // there are lots of generics here, this just allows us to use this system with a whole bunch of different systems, like Mercurial
  Map<Layers, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>> pasteurizedGamepadMap = new HashMap<Layers, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>>(){{
  	put(Layers.TELEOP, teleopGamepad);
  	put(Layers.ENDGAME, endgameGamepad);
  }};
  MapLayeringSystem<Layers, EnhancedDoubleSupplier, EnhancedBooleanSupplier, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>> enumLayeringSystem = new MapLayeringSystem<>(Layers.TELEOP, pasteurizedGamepadMap);

  // LayeredGamepad takes a LayeringSystem and makes a gamepad from it
  LayeredGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>> layeredGamepad = new LayeredGamepad<>(enumLayeringSystem);

  layeredGamepad.a(); // a from teleopGamepad
  enumLayeringSystem.setLayer(Layers.ENDGAME);
  layeredGamepad.a(); // a from endgameGamepad

  // there are many more options for a layering system, and its fairly easy to implement your own!
  // additionally, you can nest layered gamepads in other layered gamepads

  // linking across layers using or
  teleopGamepad.b(teleopGamepad.b().or(endgameGamepad.b()));
  endgameGamepad.b(teleopGamepad.b());
  // now b on both layers is linked!

  // returns true if this gamepad is active on this layering system
  enumLayeringSystem.isActive(teleopGamepad);

  enumLayeringSystem.getLayer(); // current layer
  enumLayeringSystem.getGamepad(); // current gamepad

  //
  // Other Layering Systems
  //
  // the map layering system can be used for any hashable type, but is probably best for enums
  Map<String, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>> pasteurizedGamepadMap2 = new HashMap<>();
  pasteurizedGamepadMap2.put("one", teleopGamepad);
  pasteurizedGamepadMap2.put("two", endgameGamepad);
  MapLayeringSystem<String, EnhancedDoubleSupplier, EnhancedBooleanSupplier, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>> stringLayeringSystem = new MapLayeringSystem<>("one", pasteurizedGamepadMap2);

  // list layering system can move linearly
  ListLayeringSystem<EnhancedDoubleSupplier, EnhancedBooleanSupplier, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>> listLayeringSystem = new ListLayeringSystem<>(teleopGamepad, endgameGamepad);

  // next in the list
  listLayeringSystem.next();
  // previous in the list
  listLayeringSystem.previous();
  // you can't go out of bounds

  // wrapping layering system is similar, but when you reach the end of the bounds, it wraps back to the start
  WrappingLayeringSystem<EnhancedDoubleSupplier, EnhancedBooleanSupplier, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>> wrappingLayeringSystem = new WrappingLayeringSystem<>(teleopGamepad, endgameGamepad);

  // next in the list
  wrappingLayeringSystem.next();
  // we've reached the end, so back to the start
  wrappingLayeringSystem.next();
  // we've reached the start of the list, so back to the end
  wrappingLayeringSystem.previous();
  ```

  ```kt Kotlin theme={null}
  // we'll use this enum
  enum class Layers {
  	TELEOP,
  	ENDGAME
  }

  // WARNING: once you add a gamepad to a layering system, it will cease to function normally
  // when a gamepad is put into a layering system, it is modified to go to being 'at-rest' when its not the active layer for the system
  // 'at-rest' gamepads have 0 for all axis, and false for all buttons

  // If you want to get more advanced, you can use a layering system to control the layers of your gamepad
  // gamepads on inactive layers will immediately go to an 'at-rest' state, layering systems achieve this by modifying all gamepads given to it
  val teleopGamepad = SDKGamepad(gamepad1)

  // WARNING: if your layering system is not very stable, you will need to be careful, as a layered gamepad will crash if it can't find a gamepad for the current layer
  val endgameGamepad = SDKGamepad(gamepad1)

  val pasteurizedGamepadMap = mapOf(
  	Layers.TELEOP to teleopGamepad,
  	Layers.ENDGAME to endgameGamepad
  )
  val enumLayeringSystem = MapLayeringSystem(Layers.TELEOP, pasteurizedGamepadMap)

  // LayeredGamepad takes a LayeringSystem and makes a gamepad from it
  val layeredGamepad = LayeredGamepad(enumLayeringSystem)

  layeredGamepad.a // a from teleopGamepad
  enumLayeringSystem.layer = Layers.ENDGAME
  layeredGamepad.a // a from endgameGamepad

  // there are many more options for a layering system, and its fairly easy to implement your own!
  // additionally, you can nest layered gamepads in other layered gamepads

  // linking across layers using or
  teleopGamepad.b = teleopGamepad.b.or(endgameGamepad.b)
  endgameGamepad.b = teleopGamepad.b
  // now b on both layers is linked!

  // returns true if this gamepad is active on this layering system
  enumLayeringSystem.isActive(teleopGamepad)

  enumLayeringSystem.layer // current layer
  enumLayeringSystem.gamepad // current gamepad

  //
  // Other Layering Systems
  //
  // the map layering system can be used for any hashable type, but is probably best for enums
  val pasteurizedGamepadMap2: MutableMap<String, PasteurizedGamepad<EnhancedDoubleSupplier, EnhancedBooleanSupplier>> =
  	HashMap()
  pasteurizedGamepadMap2["one"] = teleopGamepad
  pasteurizedGamepadMap2["two"] = endgameGamepad
  val stringLayeringSystem = MapLayeringSystem("one", pasteurizedGamepadMap2)


  // list layering system can move linearly
  val listLayeringSystem = ListLayeringSystem(
  		teleopGamepad,
  		endgameGamepad
  	)

  // next in the list
  listLayeringSystem.next()
  // previous in the list
  listLayeringSystem.previous()
  // you can't go out of bounds

  // wrapping layering system is similar, but when you reach the end of the bounds, it wraps back to the start
  val wrappingLayeringSystem = WrappingLayeringSystem(
  		teleopGamepad,
  		endgameGamepad
  	)

  // next in the list
  wrappingLayeringSystem.next()
  // we've reached the end, so back to the start
  wrappingLayeringSystem.next()
  // we've reached the start of the list, so back to the end
  wrappingLayeringSystem.previous()
  ```
</CodeGroup>

You can then write code to figure out when to change layers, or write your own.

Pasteurized uses a bunch of generics in order to allow it to work with systems
like Mercurial, which is much nicer in Kotlin than in Java.
