Path: blob/master/SLICK_HOME/src/org/newdawn/slick/command/InputProvider.java
1456 views
package org.newdawn.slick.command;12import java.util.ArrayList;3import java.util.HashMap;4import java.util.Iterator;5import java.util.List;6import java.util.Map;78import org.newdawn.slick.Input;9import org.newdawn.slick.util.InputAdapter;1011/**12* The central provider that maps real device input into abstract commands13* defined by the developer. Registering a control against an command with this14* class will cause the provider to produce an event for the command when the15* input is pressed and released.16*17* @author joverton18*/19public class InputProvider {20/** The commands that have been defined */21private HashMap commands;2223/** The list of listeners that may be listening */24private ArrayList listeners = new ArrayList();2526/** The input context we're responding to */27private Input input;2829/** The command input states */30private HashMap commandState = new HashMap();3132/** True if this provider is actively sending events */33private boolean active = true;3435/**36* Create a new input proider which will provide abstract input descriptions37* based on the input from the supplied context.38*39* @param input40* The input from which this provider will receive events41*/42public InputProvider(Input input) {43this.input = input;4445input.addListener(new InputListenerImpl());46commands = new HashMap();47}4849/**50* Get the list of commands that have been registered with the provider,51* i.e. the commands that can be issued to the listeners52*53* @return The list of commands (@see Command) that can be issued from this54* provider55*/56public List getUniqueCommands() {57List uniqueCommands = new ArrayList();5859for (Iterator it = commands.values().iterator(); it.hasNext();) {60Command command = (Command) it.next();6162if (!uniqueCommands.contains(command)) {63uniqueCommands.add(command);64}65}6667return uniqueCommands;68}6970/**71* Get a list of the registered controls (@see Control) that can cause a72* particular command to be invoked73*74* @param command75* The command to be invoked76* @return The list of controls that can cause the command (@see Control)77*/78public List getControlsFor(Command command) {79List controlsForCommand = new ArrayList();8081for (Iterator it = commands.entrySet().iterator(); it.hasNext();) {82Map.Entry entry = (Map.Entry) it.next();83Control key = (Control) entry.getKey();84Command value = (Command) entry.getValue();8586if (value == command) {87controlsForCommand.add(key);88}89}90return controlsForCommand;91}9293/**94* Indicate whether this provider should be sending events95*96* @param active97* True if this provider should be sending events98*/99public void setActive(boolean active) {100this.active = active;101}102103/**104* Check if this provider should be sending events105*106* @return True if this provider should be sending events107*/108public boolean isActive() {109return active;110}111112/**113* Add a listener to the provider. This listener will be notified of114* commands detected from the input.115*116* @param listener117* The listener to be added118*/119public void addListener(InputProviderListener listener) {120listeners.add(listener);121}122123/**124* Remove a listener from this provider. The listener will no longer be125* provided with notification of commands performe.126*127* @param listener128* The listener to be removed129*/130public void removeListener(InputProviderListener listener) {131listeners.remove(listener);132}133134/**135* Bind an command to a control.136*137* @param command138* The command to bind to139* @param control140* The control that is pressed/released to represent the command141*/142public void bindCommand(Control control, Command command) {143commands.put(control, command);144145if (commandState.get(command) == null) {146commandState.put(command, new CommandState());147}148}149150/**151* Clear all the controls that have been configured for a given command152*153* @param command The command whose controls should be unbound154*/155public void clearCommand(Command command) {156List controls = getControlsFor(command);157158for (int i=0;i<controls.size();i++) {159unbindCommand((Control) controls.get(i));160}161}162163/**164* Unbinds the command associated with this control165*166* @param control167* The control to remove168*/169public void unbindCommand(Control control) {170Command command = (Command) commands.remove(control);171if (command != null) {172if (!commands.keySet().contains(command)) {173commandState.remove(command);174}175}176}177178/**179* Get the recorded state for a given command180*181* @param command182* The command to get the state for183* @return The given command state184*/185private CommandState getState(Command command) {186return (CommandState) commandState.get(command);187}188189/**190* Check if the last control event we recieved related to the given command191* indicated that a control was down192*193* @param command194* The command to check195* @return True if the last event indicated a button down196*/197public boolean isCommandControlDown(Command command) {198return getState(command).isDown();199}200201/**202* Check if one of the controls related to the command specified has been203* pressed since we last called this method204*205* @param command206* The command to check207* @return True if one of the controls has been pressed208*/209public boolean isCommandControlPressed(Command command) {210return getState(command).isPressed();211}212213/**214* Fire notification to any interested listeners that a control has been215* pressed indication an particular command216*217* @param command218* The command that has been pressed219*/220protected void firePressed(Command command) {221getState(command).down = true;222getState(command).pressed = true;223224if (!isActive()) {225return;226}227228for (int i = 0; i < listeners.size(); i++) {229((InputProviderListener) listeners.get(i)).controlPressed(command);230}231}232233/**234* Fire notification to any interested listeners that a control has been235* released indication an particular command should be stopped236*237* @param command238* The command that has been pressed239*/240protected void fireReleased(Command command) {241getState(command).down = false;242243if (!isActive()) {244return;245}246247for (int i = 0; i < listeners.size(); i++) {248((InputProviderListener) listeners.get(i)).controlReleased(command);249}250}251252/**253* A token representing the state of all the controls causing an command to254* be invoked255*256* @author kevin257*/258private class CommandState {259/** True if one of the controls for this command is down */260private boolean down;261262/** True if one of the controls for this command is pressed */263private boolean pressed;264265/**266* Check if a control for the command has been pressed since last call.267*268* @return True if the command has been pressed269*/270public boolean isPressed() {271if (pressed) {272pressed = false;273return true;274}275276return false;277}278279/**280* Check if the last event we had indicated the control was pressed281*282* @return True if the control was pressed283*/284public boolean isDown() {285return down;286}287}288289/**290* A simple listener to respond to input and look up any required commands291*292* @author kevin293*/294private class InputListenerImpl extends InputAdapter {295/**296* @see org.newdawn.slick.util.InputAdapter#isAcceptingInput()297*/298public boolean isAcceptingInput() {299return true;300}301302/**303* @see org.newdawn.slick.util.InputAdapter#keyPressed(int, char)304*/305public void keyPressed(int key, char c) {306Command command = (Command) commands.get(new KeyControl(key));307if (command != null) {308firePressed(command);309}310}311312/**313* @see org.newdawn.slick.util.InputAdapter#keyReleased(int, char)314*/315public void keyReleased(int key, char c) {316Command command = (Command) commands.get(new KeyControl(key));317if (command != null) {318fireReleased(command);319}320}321322/**323* @see org.newdawn.slick.util.InputAdapter#mousePressed(int, int, int)324*/325public void mousePressed(int button, int x, int y) {326Command command = (Command) commands.get(new MouseButtonControl(327button));328if (command != null) {329firePressed(command);330}331}332333/**334* @see org.newdawn.slick.util.InputAdapter#mouseReleased(int, int, int)335*/336public void mouseReleased(int button, int x, int y) {337Command command = (Command) commands.get(new MouseButtonControl(338button));339if (command != null) {340fireReleased(command);341}342}343344/**345* @see org.newdawn.slick.util.InputAdapter#controllerLeftPressed(int)346*/347public void controllerLeftPressed(int controller) {348Command command = (Command) commands349.get(new ControllerDirectionControl(controller,350ControllerDirectionControl.LEFT));351if (command != null) {352firePressed(command);353}354}355356/**357* @see org.newdawn.slick.util.InputAdapter#controllerLeftReleased(int)358*/359public void controllerLeftReleased(int controller) {360Command command = (Command) commands361.get(new ControllerDirectionControl(controller,362ControllerDirectionControl.LEFT));363if (command != null) {364fireReleased(command);365}366}367368/**369* @see org.newdawn.slick.util.InputAdapter#controllerRightPressed(int)370*/371public void controllerRightPressed(int controller) {372Command command = (Command) commands373.get(new ControllerDirectionControl(controller,374ControllerDirectionControl.RIGHT));375if (command != null) {376firePressed(command);377}378}379380/**381* @see org.newdawn.slick.util.InputAdapter#controllerRightReleased(int)382*/383public void controllerRightReleased(int controller) {384Command command = (Command) commands385.get(new ControllerDirectionControl(controller,386ControllerDirectionControl.RIGHT));387if (command != null) {388fireReleased(command);389}390}391392/**393* @see org.newdawn.slick.util.InputAdapter#controllerUpPressed(int)394*/395public void controllerUpPressed(int controller) {396Command command = (Command) commands397.get(new ControllerDirectionControl(controller,398ControllerDirectionControl.UP));399if (command != null)400firePressed(command);401}402403/**404* @see org.newdawn.slick.util.InputAdapter#controllerUpReleased(int)405*/406public void controllerUpReleased(int controller) {407Command command = (Command) commands408.get(new ControllerDirectionControl(controller,409ControllerDirectionControl.UP));410if (command != null) {411fireReleased(command);412}413}414415/**416* @see org.newdawn.slick.util.InputAdapter#controllerDownPressed(int)417*/418public void controllerDownPressed(int controller) {419Command command = (Command) commands420.get(new ControllerDirectionControl(controller,421ControllerDirectionControl.DOWN));422if (command != null) {423firePressed(command);424}425}426427/**428* @see org.newdawn.slick.util.InputAdapter#controllerDownReleased(int)429*/430public void controllerDownReleased(int controller) {431Command command = (Command) commands432.get(new ControllerDirectionControl(controller,433ControllerDirectionControl.DOWN));434if (command != null) {435fireReleased(command);436}437}438439/**440* @see org.newdawn.slick.util.InputAdapter#controllerButtonPressed(int,441* int)442*/443public void controllerButtonPressed(int controller, int button) {444Command command = (Command) commands445.get(new ControllerButtonControl(controller, button));446if (command != null) {447firePressed(command);448}449}450451/**452* @see org.newdawn.slick.util.InputAdapter#controllerButtonReleased(int,453* int)454*/455public void controllerButtonReleased(int controller, int button) {456Command command = (Command) commands457.get(new ControllerButtonControl(controller, button));458if (command != null) {459fireReleased(command);460}461}462};463}464465466