Explorar o código

Adds the following APIs to the Gamepad class:
unsigned int getButtonCount() const;
unsigned int getJoystickCount() const;
const char* getId() const;
void draw();
void update();
Refactors and cleans up code in Gamepad class.
Removes JOYSTICK_EVENT and BUTTON_EVENT from GamepadEvent
Changes Gamepad class so that it only receives ATTACHED_EVENT and DETACHED_EVENT
No longer implements Control::Listener
Functionally, the Gamepad class can only be polled now. No more button/joystick input events.
Makes bool isContainer() const on Control public.
Refactors Game class
Makes createGamepad() private. Gamepad's can only be created by the system (or specified in a .config) and not dynamically by the developer.

Kieran Cunney %!s(int64=13) %!d(string=hai) anos
pai
achega
c1c7be078f

+ 6 - 8
gameplay/src/Container.h

@@ -177,6 +177,11 @@ public:
      */
     Animation* getAnimation(const char* id = NULL) const;
 
+    /**
+     * @see Control::isContainer
+     */
+    bool isContainer() const;
+
     /**
      * @see Control::getType
      */
@@ -286,14 +291,7 @@ protected:
      * @param layoutString The layout string to parse
      */
     static Layout::Type getLayoutType(const char* layoutString);
-
-    /**
-     * Returns whether this control is a container.
-     *
-     * @return true if this is a container, false if not.
-     */
-    bool isContainer() const;
-
+    
     /**
      * Returns whether this container or any of its controls have been modified and require an update.
      * 

+ 5 - 10
gameplay/src/Control.cpp

@@ -6,9 +6,9 @@ namespace gameplay
 {
 
 Control::Control()
-    : _id(""), _state(Control::NORMAL), _bounds(Rectangle::empty()), _clipBounds(Rectangle::empty()), _viewportClipBounds(Rectangle::empty()),
-    _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(true), _listeners(NULL), _contactIndex(INVALID_CONTACT_INDEX), _data(NULL),
-    _styleOverridden(false), _skin(NULL)
+    : _id(""), _state(Control::NORMAL), _bounds(Rectangle::empty()), _clipBounds(Rectangle::empty()), _viewportClipBounds(Rectangle::empty()),
+    _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(true), _listeners(NULL), _contactIndex(INVALID_CONTACT_INDEX),
+    _styleOverridden(false), _skin(NULL)
 {
 }
 
@@ -32,11 +32,6 @@ Control::~Control()
     {
         SAFE_DELETE(_style);
     }
-
-    if (_data)
-    {
-        SAFE_DELETE(_data);
-    }
 }
 
 void Control::initialize(Theme::Style* style, Properties* properties)
@@ -749,7 +744,7 @@ bool Control::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int conta
             y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
         {
             // Leave this control in the FOCUS state.
-            notifyListeners(Listener::CLICK);
+            notifyListeners(Listener::CLICK);
         }
 
         return _consumeInputEvents;
@@ -1138,7 +1133,7 @@ void Control::setAnimationPropertyValue(int propertyId, AnimationValue* value, f
         _dirty = true;
         break;
     case ANIMATE_OPACITY:
-        _dirty = true;
+        _dirty = true;
         break;
     }
 }

+ 14 - 30
gameplay/src/Control.h

@@ -25,7 +25,6 @@ class Control : public Ref, public AnimationTarget
     friend class AbsoluteLayout;
     friend class VerticalLayout;
     friend class FlowLayout;
-    friend class Gamepad;
 
 public:
 
@@ -698,6 +697,20 @@ public:
      */
     void setFocusIndex(int focusIndex);
 
+    /**
+     * Returns whether this Control object is a Container or not.
+     *
+     * @return true if this object is of class Container, false otherwise.
+     */
+    virtual bool isContainer() const;
+
+    /**
+     * Gets the type of the Control and returns it as a string.
+     *
+     * @return The string of the Control type, all in lower-case.
+     */
+    virtual const char* getType() const;
+
     /**
      * Add a listener to be notified of specific events affecting
      * this control.  Event types can be OR'ed together.
@@ -710,13 +723,6 @@ public:
      */
     virtual void addListener(Control::Listener* listener, int eventFlags);
 
-    /**
-     * Gets the type of the Control and returns it as a string.
-     *
-     * @return The string of the Control type, all in lower-case.
-     */
-    virtual const char* getType() const;
-
     /**
      * @see AnimationTarget#getAnimationPropertyComponentCount
      */
@@ -841,23 +847,6 @@ protected:
      */
     virtual void initialize(Theme::Style* style, Properties* properties);
 
-    /**
-     * Initialize properties common to all Controls.
-     *
-     * @param id This control's ID.
-     * @param style The style to apply to this control.
-     * @param position This control's position.
-     * @param size This control's size.
-     */
-    //virtual void initialize(const char* id, Theme::Style* style, const Vector2& position, const Vector2& size);
-
-    /**
-     * Container and classes that extend it should implement this and return true.
-     *
-     * @return true if this object is of class Container, false otherwise.
-     */
-    virtual bool isContainer() const;
-
     /**
      * Returns whether this control has been modified and requires an update.
      *
@@ -999,11 +988,6 @@ protected:
      */
     int _focusIndex;
 
-    /**
-     * Internal pointer to some data binding.
-     */
-    void* _data;
-
 private:
 
     /*

+ 13 - 45
gameplay/src/Game.cpp

@@ -20,8 +20,7 @@ Game::Game()
     : _initialized(false), _state(UNINITIALIZED), 
       _frameLastFPS(0), _frameCount(0), _frameRate(0), 
       _clearDepth(1.0f), _clearStencil(0), _properties(NULL),
-      _animationController(NULL), _audioController(NULL), _physicsController(NULL), _audioListener(NULL), 
-      _gamepadCount(0), _gamepads(NULL)
+      _animationController(NULL), _audioController(NULL), _physicsController(NULL), _audioListener(NULL)
 {
     GP_ASSERT(__gameInstance == NULL);
     __gameInstance = this;
@@ -124,16 +123,13 @@ void Game::shutdown()
 
         Platform::signalShutdown();
         finalize();
-
-        if (_gamepads)
+        
+        for (std::vector<Gamepad*>::iterator itr = _gamepads.begin(); itr != _gamepads.end(); itr++)
         {
-            for (unsigned int i = 0; i < _gamepadCount; i++)
-            {
-                SAFE_DELETE(_gamepads[i]);
-            }
-            SAFE_DELETE_ARRAY(_gamepads);
+            SAFE_DELETE((*itr));
         }
-
+        _gamepads.clear();
+        
         _animationController->finalize();
         SAFE_DELETE(_animationController);
 
@@ -218,13 +214,7 @@ void Game::frame()
     
         // Update the physics.
         _physicsController->update(elapsedTime);
-
-        if (_gamepads)
-        {
-            for (unsigned int i = 0; i < _gamepadCount; i++)
-                _gamepads[i]->update();
-        }
-
+        
         // Application Update.
         update(elapsedTime);
 
@@ -234,12 +224,6 @@ void Game::frame()
         // Graphics Rendering.
         render(elapsedTime);
         
-        if (_gamepads)
-        {
-            for (unsigned int i = 0; i < _gamepadCount; i++)
-                _gamepads[i]->render();
-        }
-
         // Update FPS.
         ++_frameCount;
         if ((Game::getGameTime() - _frameLastFPS) >= 1000)
@@ -329,7 +313,7 @@ void Game::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactI
 {
 }
 
-void Game::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int index)
+void Game::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
 {
 }
 
@@ -414,30 +398,14 @@ bool Game::TimeEvent::operator<(const TimeEvent& v) const
     return time > v.time;
 }
 
-Gamepad* Game::createGamepad(const char* gamepadFormPath)
+Gamepad* Game::createGamepad(const char* gamepadId, const char* gamepadFormPath)
 {
     GP_ASSERT(gamepadFormPath);
 
-    Gamepad* gamepad = new Gamepad(gamepadFormPath);
+    Gamepad* gamepad = new Gamepad(gamepadId, gamepadFormPath);
     GP_ASSERT(gamepad);
 
-    if (!_gamepads)
-    {
-        _gamepadCount++;
-        _gamepads = new Gamepad*[_gamepadCount];
-        _gamepads[0] = gamepad;
-    }
-    else
-    {
-        int oldSize = _gamepadCount;
-        _gamepadCount++;
-        Gamepad** tempGamepads = new Gamepad*[_gamepadCount];
-        memcpy(tempGamepads, _gamepads, sizeof(Gamepad*) * oldSize);
-        tempGamepads[oldSize] = gamepad;
-        
-        SAFE_DELETE_ARRAY(_gamepads);
-        _gamepads = tempGamepads;
-    }
+    _gamepads.push_back(gamepad);
 
     return gamepad;
 }
@@ -448,13 +416,13 @@ void Game::loadGamepad()
     {
         // Check if there is a virtual keyboard included in the .config file.
         // If there is, try to create it and assign it to "player one".
-        Properties* gamepadProperties = _properties->getNamespace("gamepad", true);
+        Properties* gamepadProperties = _properties->getNamespace("gamepads", true);
         if (gamepadProperties && gamepadProperties->exists("form"))
         {
             const char* gamepadFormPath = gamepadProperties->getString("form");
             GP_ASSERT(gamepadFormPath);
 
-            Gamepad* gamepad = createGamepad(gamepadFormPath);
+            Gamepad* gamepad = createGamepad(gamepadProperties->getId(), gamepadFormPath);
             GP_ASSERT(gamepad);
         }
     }

+ 20 - 22
gameplay/src/Game.h

@@ -25,7 +25,7 @@ class Game
 {
 
 public:
-
+    
     /**
      * The game states.
      */
@@ -274,9 +274,8 @@ public:
      *
      * @param evt The gamepad event that occurred.
      * @param gamepad the gamepad the event occurred on
-     * @param index The joystick or button index that triggered the event.
      */
-    virtual void gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int index);
+    virtual void gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad);
 
     /**
      * Sets muli-touch is to be enabled/disabled. Default is disabled.
@@ -309,29 +308,21 @@ public:
      * @param cookie The cookie data that the time event will contain.
      */
     void schedule(float timeOffset, TimeListener* timeListener, void* cookie = 0);
-
-    /** 
-     * Creates a Gamepad object from a .form file.
-     *
-     * @param playerIndex
-     * @param formPath
-     */
-    Gamepad* createGamepad(const char* gamepadFormPath);
-
-    /**
-     * Gets the gamepad for the specified player index.
-     *
-     * @param playerIndex The player index to get the gamepad for (0 <= playerIndex <= 3) 
-     */
-    inline Gamepad* getGamepad(unsigned int playerIndex = 0) const;
-
+    
     /**
      * Gets the number of gamepad's connected to the game.
      * 
-     * @return the number of gamepad's connected to the game.
+     * @return The number of gamepad's connected to the game.
      */
     inline unsigned int getGamepadCount() const;
 
+    /**
+     * Gets the gamepad at the specified index.
+     *
+     * @param index The index to get the gamepad for (0 <= index <= Game::getGamepadCount) 
+     */
+    inline Gamepad* getGamepad(unsigned int index = 0) const;
+
 protected:
 
     /**
@@ -438,6 +429,14 @@ private:
      */
     void loadConfig();
 
+    /** 
+     * Creates a Gamepad object from a .form file.
+     *
+     * @param playerIndex
+     * @param formPath
+     */
+    Gamepad* createGamepad(const char* gamepadId, const char* gamepadFormPath);
+
     /**
      * Loads a gamepad from the configuration file.
      */
@@ -461,8 +460,7 @@ private:
     AudioController* _audioController;          // Controls audio sources that are playing in the game.
     PhysicsController* _physicsController;      // Controls the simulation of a physics scene and entities.
     AudioListener* _audioListener;              // The audio listener in 3D space.
-    unsigned int _gamepadCount;
-    Gamepad** _gamepads;
+    std::vector<Gamepad*> _gamepads;
     std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents; // Contains the scheduled time events.
 
     // Note: Do not add STL object member variables on the stack; this will cause false memory leaks to be reported.

+ 9 - 10
gameplay/src/Game.inl

@@ -72,19 +72,18 @@ inline void Game::displayKeyboard(bool display)
     Platform::displayKeyboard(display);
 }
 
-inline Gamepad* Game::getGamepad(unsigned int playerIndex) const
+inline unsigned int Game::getGamepadCount() const
 {
-    GP_ASSERT(playerIndex < _gamepadCount);
-
-    if (_gamepads)
-        return _gamepads[playerIndex];
-    else
-        return NULL;
+    return _gamepads.size();
 }
 
-inline unsigned int Game::getGamepadCount() const
+inline Gamepad* Game::getGamepad(unsigned int index) const
 {
-    return _gamepadCount;
-}
+    GP_ASSERT(index < _gamepads.size());
 
+    if (!_gamepads.empty())
+        return _gamepads[index];
+    else
+        return NULL;
+}
 }

+ 37 - 87
gameplay/src/Gamepad.cpp

@@ -1,49 +1,31 @@
 #include "Base.h"
 #include "Gamepad.h"
-#include "Joystick.h"
 #include "Game.h"
 
 namespace gameplay
 {
 
-Gamepad::Gamepad()
-    : _playerIndex(-1), _joystickValues(NULL), _joystickCount(0), _buttonStates(NULL), _buttonCount(0), _gamepadForm(NULL)
+Gamepad::Gamepad(const char* id)
+    : _id(id), _gamepadForm(NULL)
 {
 }
 
-Gamepad::Gamepad(const char* formPath)
-    : _playerIndex(-1), _joystickValues(NULL), _joystickCount(0), _buttonStates(NULL), _buttonCount(0), _gamepadForm(NULL)
+Gamepad::Gamepad(const char* id, const char* formPath)
+    : _id(id), _gamepadForm(NULL)
 {
     GP_ASSERT(formPath);
 
     _gamepadForm = Form::create(formPath);
     GP_ASSERT(_gamepadForm);
-
+    
     _gamepadForm->setConsumeInputEvents(false);
 
-    getGamepadControls(_gamepadForm);
-
-    if (_joystickCount > 0)
-    {
-        _joystickValues = new Vector2*[_joystickCount];
-        for (unsigned int i = 0; i < _joystickCount; i++)
-        {
-            _joystickValues[i] = new Vector2();
-        }
-    }
-    if (_buttonCount > 0)
-    {
-        _buttonStates = new ButtonState*[_buttonCount];
-        for (unsigned int i = 0; i < _buttonCount; i++)
-        {
-            _buttonStates[i] = new ButtonState();
-        }
-    }
+    bindGamepadControls(_gamepadForm);
 }
 
-void Gamepad::getGamepadControls(Form* form)
+void Gamepad::bindGamepadControls(Container* container)
 {
-    std::vector<Control*> controls = form->getControls();
+    std::vector<Control*> controls = container->getControls();
     std::vector<Control*>::iterator itr = controls.begin();
 
     for (; itr != controls.end(); itr++)
@@ -53,43 +35,42 @@ void Gamepad::getGamepadControls(Form* form)
 
         if (control->isContainer())
         {
-            getGamepadControls((Form*) control);
+            bindGamepadControls((Container*) control);
         }
         else if (std::strcmp("joystick", control->getType()) == 0)
         {
-            control->addListener(this, Control::Listener::PRESS | Control::Listener::VALUE_CHANGED | Control::Listener::RELEASE);
-            control->_data = (void*) new GamepadData(GamepadData::JOYSTICK, _joystickCount);
-            _joystickCount++;
+            control->addRef();
+            _joysticks.push_back((Joystick*) control);
         }
         else if (std::strcmp("button", control->getType()) == 0)
         {
-            control->addListener(this, Control::Listener::PRESS | Control::Listener::RELEASE);
-            control->_data = (void*) new GamepadData(GamepadData::BUTTON, _buttonCount);
-            _buttonCount++;
+            control->addRef();
+            _buttons.push_back((Button*) control);
         }   
     }
 }
 
 Gamepad::~Gamepad()
 {
-    if (_joystickValues)
+    for (std::vector<Joystick*>::iterator itr = _joysticks.begin(); itr != _joysticks.end(); itr++)
     {
-        for (unsigned int i = 0; i < _joystickCount; i++)
-            SAFE_DELETE(_joystickValues[i]);
-        SAFE_DELETE_ARRAY(_joystickValues);
+        SAFE_RELEASE((*itr));
     }
 
-    if (_buttonStates)
+    for (std::vector<Button*>::iterator itr = _buttons.begin(); itr!= _buttons.end(); itr++)
     {
-        for (unsigned int i = 0; i < _buttonCount; i++)
-           SAFE_DELETE(_buttonStates[i]);
-        SAFE_DELETE_ARRAY(_buttonStates);
+        SAFE_RELEASE((*itr));
     }
 
     if (_gamepadForm)
         SAFE_RELEASE(_gamepadForm);
 }
 
+const char* Gamepad::getId() const
+{
+    return _id.c_str();
+}
+
 void Gamepad::update()
 {
     if (_gamepadForm && _gamepadForm->isEnabled())
@@ -98,7 +79,7 @@ void Gamepad::update()
     }
 }
 
-void Gamepad::render()
+void Gamepad::draw()
 {
     if (_gamepadForm && _gamepadForm->isEnabled())
     {
@@ -106,71 +87,40 @@ void Gamepad::render()
     }
 }
 
-void Gamepad::controlEvent(Control* control, Control::Listener::EventType evt)
+unsigned int Gamepad::getButtonCount() const
 {
-    if (_gamepadForm && _gamepadForm->isEnabled() && control->_data)
-    {
-        switch(((GamepadData*)control->_data)->_controlType)
-        {
-            case GamepadData::JOYSTICK:
-            {
-                int joystickIndex = ((GamepadData*)control->_data)->_controlIndex;
-                switch (evt)
-                {
-                    case Control::Listener::PRESS:
-                    case Control::Listener::VALUE_CHANGED:
-                        _joystickValues[joystickIndex]->set(((Joystick*)control)->getValue());
-                        break;
-                    case Control::Listener::RELEASE:
-                        _joystickValues[joystickIndex]->set(0.0f, 0.0f);
-                        break;
-                }
-                Game::getInstance()->gamepadEvent(JOYSTICK_EVENT, this, joystickIndex);
-            }
-            break;
-            case GamepadData::BUTTON:
-            {
-                int buttonIndex = ((GamepadData*)control->_data)->_controlIndex;
-                switch(evt)
-                {
-                    case Control::Listener::PRESS:
-                        *_buttonStates[buttonIndex] = BUTTON_PRESSED;
-                        break;
-                    case Control::Listener::RELEASE:
-                        *_buttonStates[buttonIndex] = BUTTON_RELEASED;
-                        break;
-                }
-                Game::getInstance()->gamepadEvent(BUTTON_EVENT, this, buttonIndex);
-            }
-            break;
-        }
-    }
+    return _buttons.size();
 }
 
 Gamepad::ButtonState Gamepad::getButtonState(unsigned int buttonId) const
 {
-    GP_ASSERT(buttonId < _buttonCount);
+    GP_ASSERT(buttonId < _buttons.size());
 
-    return *_buttonStates[buttonId];
+    return _buttons[buttonId]->getState() == Control::ACTIVE ? BUTTON_PRESSED : BUTTON_RELEASED;
+}
+
+unsigned int Gamepad::getJoystickCount() const
+{
+    return _joysticks.size();
 }
 
 bool Gamepad::isJoystickActive(unsigned int joystickId) const
 {
-    GP_ASSERT(joystickId < _joystickCount);
+    GP_ASSERT(joystickId < _joysticks.size());
 
-    return !(_joystickValues[joystickId]->isZero());
+    return !_joysticks[joystickId]->getValue().isZero();
 }
 
 const Vector2& Gamepad::getJoystickValue(unsigned int joystickId) const
 {
-    GP_ASSERT(joystickId < _joystickCount);
+    GP_ASSERT(joystickId < _joysticks.size());
 
-    return *_joystickValues[joystickId];
+    return _joysticks[joystickId]->getValue();
 }
 
 bool Gamepad::isVirtual() const
 {
-    return (_gamepadForm && _gamepadForm->isEnabled());
+    return true;
 }
 
 Form* Gamepad::getForm() const

+ 40 - 42
gameplay/src/Gamepad.h

@@ -3,6 +3,7 @@
 
 #include "Form.h"
 #include "Button.h"
+#include "Joystick.h"
 
 namespace gameplay
 {
@@ -10,7 +11,7 @@ namespace gameplay
 /**
  * Defines an interface for handling gamepad input.
  */
-class Gamepad : public Control::Listener
+class Gamepad
 {
     friend class Game;
     friend class Control;
@@ -22,10 +23,8 @@ public:
      */
     enum GamepadEvent
     {
-        CONNECTED_EVENT,
-        DISCONNECTED_EVENT,
-        JOYSTICK_EVENT,
-        BUTTON_EVENT
+        ATTACHED_EVENT,
+        DETACHED_EVENT,
     };
 
     /**
@@ -36,7 +35,21 @@ public:
         BUTTON_PRESSED = gameplay::Button::Listener::PRESS, 
         BUTTON_RELEASED = gameplay::Button::Listener::RELEASE
     };
-    
+
+    /**
+     * Gets the Gamepad's ID.
+     *
+     * @return the Gamepad's ID.
+     */
+    const char* getId() const;
+
+    /**
+     * Gets the number of button on the gamepad.
+     *
+     * @return the number of buttons on the gamepad.
+     */
+    unsigned int getButtonCount() const;
+
     /** 
      * Gets the current state of the specified button.
      *
@@ -44,6 +57,13 @@ public:
      * @return whether the button is currently pressed or not.
      */
     ButtonState getButtonState(unsigned int buttonId) const;
+    
+    /**
+     * Gets the number of joysticks on the gamepad.
+     *
+     * @return the number of joysticks on the gamepad.
+     */
+    unsigned int getJoystickCount() const;
 
     /**
      * Gets whether the specified joystick's state is active or not.
@@ -78,32 +98,22 @@ public:
      */
     Form* getForm() const;
 
-protected:
+    /**
+     * Updates the gamepad.
+     */
+    void update();
 
     /**
-     * @see Control::Listener::controlEvent
+     * Draws the gamepad if it is based on a form and if the form is enabled.
      */
-    void controlEvent(Control* control, Control::Listener::EventType evt);
+    void draw();
 
 private:
-    
-    struct GamepadData
-    {
-        enum {JOYSTICK, BUTTON};
-
-        GamepadData(unsigned int controlType, unsigned int controlIndex)
-            : _controlType(controlType), _controlIndex(controlIndex) {}
-
-        ~GamepadData();
-
-        unsigned int _controlType;
-        unsigned int _controlIndex;
-    };
 
     /**
      * Constructor.
      */
-    Gamepad();
+    Gamepad(const char* id);
     
     /**
      * Constructor.
@@ -111,7 +121,7 @@ private:
      *
      * @param formPath
      */ 
-    Gamepad(const char* formPath);
+    Gamepad(const char* id, const char* formPath);
 
     /**
      * Copy constructor.
@@ -122,27 +132,15 @@ private:
      * Destructor.
      */
     virtual ~Gamepad();
-    
-    /** 
-     * Gets the Joystick and Button Control object's from the specified form.
-     */
-    void getGamepadControls(Form* form);
 
-    /**
-     * Updates the gamepad.
+    /** 
+     * Binds the Joystick and Button Control object's from the specified container.
      */
-    void update();
+    void bindGamepadControls(Container* container);
 
-    /**
-     * Renders the gamepad if it is based on a form and if the form is enabled.
-     */
-    void render();
-    
-    int _playerIndex;
-    Vector2** _joystickValues;
-    unsigned int _joystickCount;
-    ButtonState** _buttonStates;
-    unsigned int _buttonCount;
+    std::string _id;
+    std::vector<Joystick*> _joysticks;
+    std::vector<Button*> _buttons;
     Form* _gamepadForm;
 };