<commit_before>/*
 * Copyright (c) 2003-2006 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 
 *   may be used to endorse or promote products derived from this software 
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jme.input;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.InputActionInterface;
import com.jme.input.action.MouseInputAction;
import com.jme.input.joystick.Joystick;
import com.jme.input.joystick.JoystickInput;
import com.jme.input.joystick.JoystickInputHandlerDevice;
import com.jme.input.keyboard.KeyboardInputHandlerDevice;
import com.jme.input.mouse.MouseInputHandlerDevice;
import com.jme.input.util.SyntheticAxis;
import com.jme.input.util.SyntheticButton;

/**
 * <code>InputHandler</code> handles mouse, key and other inputs. Actions can be subscribed for specific event triggers.
 * {@link InputActionInterface#performAction(InputActionEvent)} is invoked within the {@link #update} method whenever the
 * trigger criterias match. For a usage example see TestInputHandler. InputHandler is also used to decouple event
 * occurence and action invocation (see {@link ActionTrigger}) - an event may occur in another thread (e.g. polling
 * thread) but the action is still invoked in the thread that is calling the {@link #update} method.
 * <br>
 * You can add custom devices via the {@link #addDevice(InputHandlerDevice)} method.
 *
 * @author <NAME>
 * @author <NAME> - (javadoc only)
 * @author Irrisor - revamp
 * @version $Id: InputHandler.java,v 1.45 2007-11-01 14:35:53 irrisor Exp $
 */
public class InputHandler {
    private static final Logger logger = Logger.getLogger(InputHandler.class.getName());

    /**
     * Stores first active trigger that is invoked upon next update. Other active triggers are reachable via
     * {@link ActionTrigger#getNext()} (linked list).
     */
    ActionTrigger activeTriggers;

    /**
     * list of all {@link ActionTrigger}s of this input handler (triggers add themselves).
     */
    final ArrayList<ActionTrigger> allTriggers = new ArrayList<ActionTrigger>();

    /**
     * Device name of the mouse.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final String DEVICE_MOUSE = "mouse";
    /**
     * Device name of the keyboard.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final String DEVICE_KEYBOARD = "keyboard";

    /**
     * Wildcard device name for all devices.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final String DEVICE_ALL = "ALL DEVICES";

    /**
     * int value for representing no button/key.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final int BUTTON_NONE = -1;
    /**
     * int value for representing all buttons/keys (wildcard).
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final int BUTTON_ALL = Integer.MIN_VALUE;
    /**
     * int value for representing no axis.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final int AXIS_NONE = -1;
    /**
     * int value for representing all axes (wildcard).
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final int AXIS_ALL = Integer.MIN_VALUE;

    /** Not used any more. */
    protected Mouse mouse; //todo: remove this field in .11

    /**
     * event that will be used to call each action this frame.
     */
    protected InputActionEvent event = new InputActionEvent();

    /**
     * Creates a new input handler. By default, there are no keyboard actions or
     * mouse actions defined.
     */
    public InputHandler() {
        initializeDefaultDevices();
    }

    /**
     * Sets the speed of all actions currently registered with this handler to
     * the given value.
     *
     * @param speed The new speed for all currently registered actions.
     * @see com.jme.input.action.InputAction#setSpeed(float)
     */
    public void setActionSpeed( float speed ) {
        setActionSpeed( speed, null );
    }
    
    public void setActionSpeed(float speed, String trigger) {
        synchronized ( this ) {
            if ( allTriggers != null ) {
                for ( int i = allTriggers.size() - 1; i >= 0; i-- ) {
                    ActionTrigger actionTrigger = allTriggers.get( i );
                    if ( trigger == null || trigger.equals( actionTrigger.name ) ) {
                        if ( actionTrigger.action instanceof InputAction ) {
                            InputAction inputAction = (InputAction) actionTrigger.action;
                            inputAction.setSpeed( speed );
                        }
                    }
                }
            }
        }
    }

    /**
     * Adds an input action to be invoked by this handler during update.
     *
     * @param inputAction    the input action to be added
     * @param triggerCommand the command to trigger this action (registered with {@link com.jme.input.KeyBindingManager}), if null
 *                       the action is invoked on each call of {@link #update}
     * @param allowRepeats   true to invoke the action every call of update the trigger is lit, false to invoke
     */
    public void addAction( InputActionInterface inputAction, String triggerCommand, boolean allowRepeats ) {
        // noinspection deprecation
        new ActionTrigger.CommandTrigger( this, triggerCommand, inputAction, allowRepeats );
    }

    /**
     * Registeres a single key as command in {@link KeyBindingManager} and adds an input
     * action to be invoked by this handler during update.
     *
     * @param inputAction    the input action to be added
     * @param triggerCommand the command to trigger this action, may not be null (unlike in
     *                       {@link #addAction(com.jme.input.action.InputActionInterface,String,boolean)})
     * @param keyCode        the keyCode to register at {@link com.jme.input.KeyBindingManager} for the command
     * @param allowRepeats   true to invoke the action every call of update the trigger is lit, false to invoke<commit_msg>Issue 262: unneeded !=null-check removed<commit_after>/*
 * Copyright (c) 2003-2006 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 
 *   may be used to endorse or promote products derived from this software 
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jme.input;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.InputActionInterface;
import com.jme.input.action.MouseInputAction;
import com.jme.input.joystick.Joystick;
import com.jme.input.joystick.JoystickInput;
import com.jme.input.joystick.JoystickInputHandlerDevice;
import com.jme.input.keyboard.KeyboardInputHandlerDevice;
import com.jme.input.mouse.MouseInputHandlerDevice;
import com.jme.input.util.SyntheticAxis;
import com.jme.input.util.SyntheticButton;

/**
 * <code>InputHandler</code> handles mouse, key and other inputs. Actions can be subscribed for specific event triggers.
 * {@link InputActionInterface#performAction(InputActionEvent)} is invoked within the {@link #update} method whenever the
 * trigger criterias match. For a usage example see TestInputHandler. InputHandler is also used to decouple event
 * occurence and action invocation (see {@link ActionTrigger}) - an event may occur in another thread (e.g. polling
 * thread) but the action is still invoked in the thread that is calling the {@link #update} method.
 * <br>
 * You can add custom devices via the {@link #addDevice(InputHandlerDevice)} method.
 *
 * @author <NAME>
 * @author <NAME> - (javadoc only)
 * @author Irrisor - revamp
 * @version $Id: InputHandler.java,v 1.46 2007-11-01 14:38:03 irrisor Exp $
 */
public class InputHandler {
    private static final Logger logger = Logger.getLogger(InputHandler.class.getName());

    /**
     * Stores first active trigger that is invoked upon next update. Other active triggers are reachable via
     * {@link ActionTrigger#getNext()} (linked list).
     */
    ActionTrigger activeTriggers;

    /**
     * list of all {@link ActionTrigger}s of this input handler (triggers add themselves).
     */
    final ArrayList<ActionTrigger> allTriggers = new ArrayList<ActionTrigger>();

    /**
     * Device name of the mouse.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final String DEVICE_MOUSE = "mouse";
    /**
     * Device name of the keyboard.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final String DEVICE_KEYBOARD = "keyboard";

    /**
     * Wildcard device name for all devices.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final String DEVICE_ALL = "ALL DEVICES";

    /**
     * int value for representing no button/key.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final int BUTTON_NONE = -1;
    /**
     * int value for representing all buttons/keys (wildcard).
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final int BUTTON_ALL = Integer.MIN_VALUE;
    /**
     * int value for representing no axis.
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final int AXIS_NONE = -1;
    /**
     * int value for representing all axes (wildcard).
     *
     * @see #addAction(com.jme.input.action.InputActionInterface,String,int,int,boolean)
     */
    public static final int AXIS_ALL = Integer.MIN_VALUE;

    /** Not used any more. */
    protected Mouse mouse; //todo: remove this field in .11

    /**
     * event that will be used to call each action this frame.
     */
    protected InputActionEvent event = new InputActionEvent();

    /**
     * Creates a new input handler. By default, there are no keyboard actions or
     * mouse actions defined.
     */
    public InputHandler() {
        initializeDefaultDevices();
    }

    /**
     * Sets the speed of all actions currently registered with this handler to
     * the given value.
     *
     * @param speed The new speed for all currently registered actions.
     * @see com.jme.input.action.InputAction#setSpeed(float)
     */
    public void setActionSpeed( float speed ) {
        setActionSpeed( speed, null );
    }
    
    public void setActionSpeed(float speed, String trigger) {
        synchronized ( this ) {
            for ( int i = allTriggers.size() - 1; i >= 0; i-- ) {
                ActionTrigger actionTrigger = allTriggers.get( i );
                if ( trigger == null || trigger.equals( actionTrigger.name ) ) {
                    if ( actionTrigger.action instanceof InputAction ) {
                        InputAction inputAction = (InputAction) actionTrigger.action;
                        inputAction.setSpeed( speed );
                    }
                }
            }
        }
    }

    /**
     * Adds an input action to be invoked by this handler during update.
     *
     * @param inputAction    the input action to be added
     * @param triggerCommand the command to trigger this action (registered with {@link com.jme.input.KeyBindingManager}), if null
 *                       the action is invoked on each call of {@link #update}
     * @param allowRepeats   true to invoke the action every call of update the trigger is lit, false to invoke
     */
    public void addAction( InputActionInterface inputAction, String triggerCommand, boolean allowRepeats ) {
        // noinspection deprecation
        new ActionTrigger.CommandTrigger( this, triggerCommand, inputAction, allowRepeats );
    }

    /**
     * Registeres a single key as command in {@link KeyBindingManager} and adds an input
     * action to be invoked by this handler during update.
     *
     * @param inputAction    the input action to be added
     * @param triggerCommand the command to trigger this action, may not be null (unlike in
     *                       {@link #addAction(com.jme.input.action.InputActionInterface,String,boolean)})
     * @param keyCode        the keyCode to register at {@link com.jme.input.KeyBindingManager} for the command
     * @param allowRepeats   true to invoke the action every call of update the trigger is lit, false to invoke
{'fraction_non_alphanumeric': 0.0849837051892705, 'fraction_numerical': 0.004073702682376536, 'mean_word_length': 3.05824008138352, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4105767', 'n_tokens_mistral': 4409, 'n_tokens_neox': 4188, 'n_words': 1562}