<commit_before>pc.extend(pc.input, function () {
    
    /**
     * @name pc.input.Controller
     * @class A general input handler which handles both mouse and keyboard input assigned to named actions.
     * This allows you to define input handlers separately to defining keyboard/mouse configurations
     * @example
     * <code>
     * <pre>
     * var c = new pc.input.Controller()
     * c.attach(document);
     * 
     * // Register the "fire" action and assign it to both the Enter key and the Spacebar.
     * c.registerKey("fire", [pc.input.KEY_ENTER, pc.input.KEY_SPACE]);
     * </pre>
     * </code>
     * @constructor Create a new instance of a Controller
     * @param {DOMElement} [element] DOMElement to attach Controller to
     */
    var Controller = function (element) {
        this._keyboard = null;
        this._mouse = null;
        this._element = null;
        
        this._actions = {};
        
        if(element) {
            this.attach(element);
        }
    };
    
    /**
     * @function
     * @name pc.input.Controller#attach
     * @description Attach Controller to a DOMElement, this is required before you can monitor for key/mouse inputs.
     * @param {DOMElement} element The element to attach mouse and keyboard event handler too
     */
    Controller.prototype.attach = function (element) {
        this._element = element;
    }
    
    /**
     * @function
     * @name pc.input.Controller#detach
     * @description Detach Controller from a DOMElement, this should be done before the Controller is destroyed 
     */
    Controller.prototype.detach = function () {
        if(this._keyboard) {
            this._keyboard.detach();
        }
        if(this._mouse) {
            this._mouse.detach();
        }
        this._element = null;
    }
    
    /**
     * @function
     * @name pc.input.Controller#disableContextMenu
     * @description Disable the context menu usually activated with the right mouse button.
     */
    Controller.prototype.disableContextMenu = function () {
        if(!this._mouse) {
            this._enableMouse();
        }
        
        this._mouse.disableContextMenu();
    };
    
    /** 
     * @function
     * @name pc.input.Controller#enableContextMenu
     * @description Enable the context menu usually activated with the right mouse button. This is enabled by default.
     */
    Controller.prototype.enableContextMenu = function () {
        if(!this._mouse) {
            this._enableMouse();
        }
        
        this._mouse.enableContextMenu();
    };
    
    /**
     * @function
     * @name pc.input.Controller#update
     * @description Update the Keyboard and Mouse handlers
     * @param {Object} dt The time since the last frame
     */
    Controller.prototype.update = function (dt) {
        if(this._keyboard) {
            this._keyboard.update(dt);
        }
    };
    
    /**
     * @function
     * @name pc.input.Controller#registerKeys
     * @description Create or update a action which is enabled when the supplied keys are pressed.
     * @param {String} action The name of the action
     * @param {Number} keys A list of keycodes
     */
    Controller.prototype.registerKeys = function (action, keys) {
        if(!this._keyboard) {
            this._enableKeyboard();
        }
        if(this._actions[action]) {
            throw new Error(pc.string.format("Action: {0} already registered", action));
        }
        if(this._actions[action]) {
            this._actions[action].push(keys);
        } else {
            this._actions[action] = keys;
        }
    };
    
    /**
     * @function
     * @name pc.input.Controller#registerMouse
     * @description Create or update an action which is enabled when the supplied mouse button is pressed
     * @param {String} action The name of the action
     * @param {Number} button The mouse button
     */
    Controller.prototype.registerMouse = function (action, button) {
        if(!this._mouse) {
            this._enableMouse();
        }

        // Mouse actions are stored as negative numbers to prevent clashing with keycodes.
        if(this._actions[action]) {
            this._actions[action].push(-button)
        } else {
            this._actions[action] = [-button]
        }
    };
    
    /**
     * @function
     * @name pc.input.Controller#isPressed
     * @description Return true if the current action is enabled
     * @param {String} action The name of the action
     */
    Controller.prototype.isPressed = function (action) {
        if(!this._actions[action]) {
            return false;
        }
        
        var key;
        var index = 0;
        var length = this._actions[action].length;
        
        for(index = 0; index < length; ++index) {
            key = this._actions[action][index];
            if(key > 0) {
                if(this._keyboard && this._keyboard.isPressed(key)) {
                    return true;
                }                
            } else {
                if(this._mouse && this._mouse.isPressed(-key)) {
                    return true;
                }
            }
        }
        return false;
    };

    /**
     * @function
     * @name pc.input.Controller#wasPressed
     * @description Returns true if the action was enabled this since the last update
     * @param {String} action The name of the action
     */
    Controller.prototype.wasPressed = function (action) {
        if(!this._actions[action]) {
            return false;
        }

        var key;
        var index = 0;
        var length = this._actions[action].length;
        
        for(index = 0; index < length; ++index) {
            key = this._actions[action][index];
            if (key > 0) {
                if(this._keyboard && this._keyboard.wasPressed(key)) {
                    return true;
                }                
            } else {
                if(this._mouse && this._mouse.wasPressed(-key)) {
                    return true;
                }
            }
        }
        return false;
    };
    
    Controller.prototype._enableMouse = function () {
        this._mouse = new pc.input.Mouse();
        if(!this._element) {
            throw new Error("Controller must be attached to a DOMElement");
        }
        this._mouse.attach(this._element);        
    };
    
    Controller.prototype._enableKeyboard = function () {
        this._keyboard = new pc.input.Keyboard();
        if(!this._element) {
            throw new Error("Controller must be attached to a DOMElement");
        }
        this._keyboard.attach(this._element);        
    };
    
    return {
        Controller: Controller
    };
}());
<commit_msg>Added support for Axes to input.Controller<commit_after>pc.extend(pc.input, function () {
    
    /**
     * @name pc.input.Controller
     * @class A general input handler which handles both mouse and keyboard input assigned to named actions.
     * This allows you to define input handlers separately to defining keyboard/mouse configurations
     * @example
     * <code>
     * <pre>
     * var c = new pc.input.Controller()
     * c.attach(document);
     * 
     * // Register the "fire" action and assign it to both the Enter key and the Spacebar.
     * c.registerKey("fire", [pc.input.KEY_ENTER, pc.input.KEY_SPACE]);
     * </pre>
     * </code>
     * @constructor Create a new instance of a Controller
     * @param {DOMElement} [element] DOMElement to attach Controller to
     */
    var Controller = function (element) {
        this._keyboard = null;
        this._mouse = null;
        this._element = null;
        
        this._actions = {};
        this._axes = {};

        if(element) {
            this.attach(element);
        }
    };
    
    /**
     * @function
     * @name pc.input.Controller#attach
     * @description Attach Controller to a DOMElement, this is required before you can monitor for key/mouse inputs.
     * @param {DOMElement} element The element to attach mouse and keyboard event handler too
     */
    Controller.prototype.attach = function (element) {
        this._element = element;
    }
    
    /**
     * @function
     * @name pc.input.Controller#detach
     * @description Detach Controller from a DOMElement, this should be done before the Controller is destroyed 
     */
    Controller.prototype.detach = function () {
        if(this._keyboard) {
            this._keyboard.detach();
        }
        if(this._mouse) {
            this._mouse.detach();
        }
        this._element = null;
    }
    
    /**
     * @function
     * @name pc.input.Controller#disableContextMenu
     * @description Disable the context menu usually activated with the right mouse button.
     */
    Controller.prototype.disableContextMenu = function () {
        if(!this._mouse) {
            this._enableMouse();
        }
        
        this._mouse.disableContextMenu();
    };
    
    /** 
     * @function
     * @name pc.input.Controller#enableContextMenu
     * @description Enable the context menu usually activated with the right mouse button. This is enabled by default.
     */
    Controller.prototype.enableContextMenu = function () {
        if(!this._mouse) {
            this._enableMouse();
        }
        
        this._mouse.enableContextMenu();
    };
    
    /**
     * @function
     * @name pc.input.Controller#update
     * @description Update the Keyboard and Mouse handlers
     * @param {Object} dt The time since the last frame
     */
    Controller.prototype.update = function (dt) {
        if(this._keyboard) {
            this._keyboard.update(dt);
        }

        if (this._mouse) {
            this._mouse.update(dt);
        }

        this._axes = {};
    };
    
    /**
     * @function
     * @name pc.input.Controller#registerKeys
     * @description Create or update a action which is enabled when the supplied keys are pressed.
     * @param {String} action The name of the action
     * @param {Number} keys A list of keycodes
     */
    Controller.prototype.registerKeys = function (action, keys) {
        if (!this._keyboard) {
            this._enableKeyboard();
        }
        if (this._actions[action]) {
            throw new Error(pc.string.format("Action: {0} already registered", action));
        }
        if (this._actions[action]) {
            this._actions[action].push(keys);
        } else {
            this._actions[action] = keys;
        }
    };
    
    /**
     * @function
     * @name pc.input.Controller#registerMouse
     * @description Create or update an action which is enabled when the supplied mouse button is pressed
     * @param {String} action The name of the action
     * @param {Number} button The mouse button
     */
    Controller.prototype.registerMouse = function (action, button) {
        if (!this._mouse) {
            this._enableMouse();
        }

        // Mouse actions are stored as negative numbers to prevent clashing with keycodes.
        if (this._actions[action]) {
            this._actions[action].push(-button)
        } else {
            this._actions[action] = [-button]
        }
    };
    
    /**
    * @function
    * @name pc.input.Controller#registerAxis
    * @description 
    * @param {Object} options
    */
    Controller.prototype.registerAxis = function (options) {
        var name = options['name'];

        var bind = function (controller, source, value) {
            switch (source) {
                case 'mouseright':
                case 'mouseleft':
                    controller._mouse.bind('mousemove', function (e) {
                        controller._axes[name] = e.movementX;
                    });
                    break;
                case 'mouseup':
                case 'mousedown':
                    controller._mouse.bind('mousemove', function (e) {
                        controller._axes[name] = -e.movementY;
                    });
                    break;
                case 'left':
                    controller._keyboard.bind('keydown', function (e) {
                        if (e.event.keyCode === pc.input.KEY_LEFT) {
                            controller._axes[name] = value;
                        }
                    });
                    break;
                case 'right':
                    controller._keyboard.bind('keydown', function (e) {
                        if (e.event.keyCode === pc.input.KEY_RIGHT) {
                            controller._axes[name] = value;
                        }
                    });
                    break;
                case 'up':
                    controller._keyboard.bind('keydown', function (e) {
                        if (e.event.keyCode === pc.input.KEY_UP) {
                            controller._axes[name] = value;
                        }
                    });
                    break;
                case 'down':
                    controller._keyboard.bind('keydown', function (e) {
                        if (e.event.keyCode === pc.input.KEY_DOWN) {
                            controller._axes[name] = value;
                        }
                    });
                    break;
                default:
                    controller._keyboard.bind('keydown', function (e) {
                        controller._axes[name] = value;
                    });
                    break;
            }
        };

        bind(this, options.positive, 1);
        bind(this, options.negative, -1);
    };

    /**
     * @function
     * @name pc.input.Controller#isPressed
     * @description Return true if the current action is enabled
     * @param {String} action The name of the action
     */
    Controller.prototype.isPressed = function (action) {
        if(!this._actions[action]) {
            return false;
        }
        
        var key;
        var index = 0;
        var length = this._actions[action].length;
        
        for(index = 0; index < length; ++index) {
            key = this._actions[action][index];
            if(key > 0) {
                if(this._keyboard && this._keyboard.isPressed(key)) {
                    return true;
                }                
            } else {
                if(this._mouse && this._mouse.isPressed(-key)) {
                    return true;
                }
            }
        }
        return false;
    };

    /**
     * @function
     * @name pc.input.Controller#wasPressed
     * @description Returns true if the action was enabled this since the last update
     * @param {String} action The name of the action
     */
    Controller.prototype.wasPressed = function (action) {
        if(!this._actions[action]) {
            return false;
        }

        var key;
        var index = 0;
        var length = this._actions[action].length;
        
        for(index = 0; index < length; ++index) {
            key = this._actions[action][index];
            if (key > 0) {
                if(this._keyboard && this._keyboard.wasPressed(key)) {
                    return true;
                }                
            } else {
                if(this._mouse && this._mouse.wasPressed(-key)) {
                    return true;
                }
            }
        }
        return false;
    };
    
    Controller.prototype.getAxis = function (name) {
        return this._axes[name] || 0;
    };

    Controller.prototype._enableMouse = function () {
        this._mouse = new pc.input.Mouse();
        if(!this._element) {
            throw new Error("Controller must be attached to a DOMElement");
        }
        this._mouse.attach(this._element);        
    };
    
    Controller.prototype._enableKeyboard = function () {
        this._keyboard = new pc.input.Keyboard();
        if(!this._element) {
            throw new Error("Controller must be attached to a DOMElement");
        }
        this._keyboard.attach(this._element);        
    };
    
    return {
        Controller: Controller
    };
}());

{'fraction_non_alphanumeric': 0.10619909220916496, 'fraction_numerical': 0.0010570167257352484, 'mean_word_length': 1.5937751975487824, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, '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': '7365493', 'n_tokens_mistral': 4222, 'n_tokens_neox': 4100, 'n_words': 1073}