Răsfoiți Sursa

Merge pull request #556 from blackberry-gaming/next-cculy

Next cculy
Sean Paul Taylor 13 ani în urmă
părinte
comite
30d6f4242a
63 a modificat fișierele cu 671 adăugiri și 643 ștergeri
  1. 2 2
      gameplay/gameplay.vcxproj
  2. 6 6
      gameplay/gameplay.vcxproj.filters
  3. 4 1
      gameplay/src/AIAgent.cpp
  4. 2 1
      gameplay/src/AIAgent.h
  5. 1 1
      gameplay/src/AIMessage.h
  6. 6 3
      gameplay/src/AIState.cpp
  7. 2 1
      gameplay/src/AIState.h
  8. 15 3
      gameplay/src/AnimationClip.cpp
  9. 19 0
      gameplay/src/AnimationClip.h
  10. 4 21
      gameplay/src/Control.cpp
  11. 2 22
      gameplay/src/Control.h
  12. 10 1
      gameplay/src/Game.cpp
  13. 19 0
      gameplay/src/Game.h
  14. 17 3
      gameplay/src/PhysicsCollisionObject.cpp
  15. 22 2
      gameplay/src/PhysicsCollisionObject.h
  16. 12 43
      gameplay/src/PhysicsController.cpp
  17. 2 18
      gameplay/src/PhysicsController.h
  18. 132 6
      gameplay/src/ScriptController.cpp
  19. 63 1
      gameplay/src/ScriptController.h
  20. 9 0
      gameplay/src/ScriptController.inl
  21. 0 56
      gameplay/src/ScriptListener.cpp
  22. 0 66
      gameplay/src/ScriptListener.h
  23. 146 0
      gameplay/src/ScriptTarget.cpp
  24. 89 0
      gameplay/src/ScriptTarget.h
  25. 9 41
      gameplay/src/Transform.cpp
  26. 2 23
      gameplay/src/Transform.h
  27. 1 1
      gameplay/src/lua/lua_AnimationClip.cpp
  28. 1 1
      gameplay/src/lua/lua_AnimationClipListener.cpp
  29. 0 1
      gameplay/src/lua/lua_AudioListener.cpp
  30. 0 1
      gameplay/src/lua/lua_AudioSource.cpp
  31. 0 16
      gameplay/src/lua/lua_Button.cpp
  32. 0 1
      gameplay/src/lua/lua_Camera.cpp
  33. 0 16
      gameplay/src/lua/lua_CheckBox.cpp
  34. 0 16
      gameplay/src/lua/lua_Container.cpp
  35. 0 16
      gameplay/src/lua/lua_Control.cpp
  36. 0 1
      gameplay/src/lua/lua_ControlListener.cpp
  37. 0 16
      gameplay/src/lua/lua_Form.cpp
  38. 0 1
      gameplay/src/lua/lua_Game.cpp
  39. 0 5
      gameplay/src/lua/lua_Global.cpp
  40. 0 38
      gameplay/src/lua/lua_Joint.cpp
  41. 0 16
      gameplay/src/lua/lua_Joystick.cpp
  42. 0 16
      gameplay/src/lua/lua_Label.cpp
  43. 0 1
      gameplay/src/lua/lua_MeshSkin.cpp
  44. 0 38
      gameplay/src/lua/lua_Node.cpp
  45. 0 1
      gameplay/src/lua/lua_NodeCloneContext.cpp
  46. 1 1
      gameplay/src/lua/lua_PhysicsCharacter.cpp
  47. 1 1
      gameplay/src/lua/lua_PhysicsCollisionObject.cpp
  48. 1 1
      gameplay/src/lua/lua_PhysicsCollisionObjectCollisionListener.cpp
  49. 1 1
      gameplay/src/lua/lua_PhysicsCollisionObjectCollisionPair.cpp
  50. 0 23
      gameplay/src/lua/lua_PhysicsController.cpp
  51. 0 1
      gameplay/src/lua/lua_PhysicsControllerHitFilter.cpp
  52. 0 1
      gameplay/src/lua/lua_PhysicsControllerHitResult.cpp
  53. 0 1
      gameplay/src/lua/lua_PhysicsControllerListener.cpp
  54. 1 1
      gameplay/src/lua/lua_PhysicsGhostObject.cpp
  55. 1 1
      gameplay/src/lua/lua_PhysicsRigidBody.cpp
  56. 1 1
      gameplay/src/lua/lua_PhysicsRigidBodyParameters.cpp
  57. 0 16
      gameplay/src/lua/lua_RadioButton.cpp
  58. 66 0
      gameplay/src/lua/lua_ScriptController.cpp
  59. 1 0
      gameplay/src/lua/lua_ScriptController.h
  60. 0 16
      gameplay/src/lua/lua_Slider.cpp
  61. 0 16
      gameplay/src/lua/lua_TextBox.cpp
  62. 0 38
      gameplay/src/lua/lua_Transform.cpp
  63. 0 1
      gameplay/src/lua/lua_TransformListener.cpp

+ 2 - 2
gameplay/gameplay.vcxproj

@@ -254,7 +254,7 @@
     <ClCompile Include="src\SceneLoader.cpp" />
     <ClCompile Include="src\ScreenDisplayer.cpp" />
     <ClCompile Include="src\ScriptController.cpp" />
-    <ClCompile Include="src\ScriptListener.cpp" />
+    <ClCompile Include="src\ScriptTarget.cpp" />
     <ClCompile Include="src\Slider.cpp" />
     <ClCompile Include="src\SpriteBatch.cpp" />
     <ClCompile Include="src\Technique.cpp" />
@@ -510,7 +510,7 @@
     <ClInclude Include="src\SceneLoader.h" />
     <ClInclude Include="src\ScreenDisplayer.h" />
     <ClInclude Include="src\ScriptController.h" />
-    <ClInclude Include="src\ScriptListener.h" />
+    <ClInclude Include="src\ScriptTarget.h" />
     <ClInclude Include="src\Slider.h" />
     <ClInclude Include="src\SpriteBatch.h" />
     <ClInclude Include="src\Technique.h" />

+ 6 - 6
gameplay/gameplay.vcxproj.filters

@@ -735,9 +735,6 @@
     <ClCompile Include="src\lua\lua_VertexFormatUsage.cpp">
       <Filter>lua</Filter>
     </ClCompile>
-    <ClCompile Include="src\ScriptListener.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
     <ClCompile Include="src\AIAgent.cpp">
       <Filter>src</Filter>
     </ClCompile>
@@ -777,6 +774,9 @@
     <ClCompile Include="src\lua\lua_AIStateMachine.cpp">
       <Filter>lua</Filter>
     </ClCompile>
+    <ClCompile Include="src\ScriptTarget.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Animation.h">
@@ -1505,9 +1505,6 @@
     <ClInclude Include="src\lua\lua_VertexFormatUsage.h">
       <Filter>lua</Filter>
     </ClInclude>
-    <ClInclude Include="src\ScriptListener.h">
-      <Filter>src</Filter>
-    </ClInclude>
     <ClInclude Include="src\AIStateMachine.h">
       <Filter>src</Filter>
     </ClInclude>
@@ -1547,6 +1544,9 @@
     <ClInclude Include="src\lua\lua_AIStateMachine.h">
       <Filter>lua</Filter>
     </ClInclude>
+    <ClInclude Include="src\ScriptTarget.h">
+      <Filter>src</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="src\gameplay-main-macosx.mm">

+ 4 - 1
gameplay/src/AIAgent.cpp

@@ -9,6 +9,8 @@ AIAgent::AIAgent()
     : _stateMachine(NULL), _node(NULL), _enabled(true), _next(NULL)
 {
     _stateMachine = new AIStateMachine(this);
+
+    addEvent("message", "<AIMessage>");
 }
 
 AIAgent::~AIAgent()
@@ -82,7 +84,8 @@ bool AIAgent::processMessage(AIMessage* message)
     if (_listener && _listener->messageReceived(message))
         return true;
     
-    // TODO: Fire script listener
+    if (fireEvent<bool>("message", message))
+        return true;
     
     return false;
 }

+ 2 - 1
gameplay/src/AIAgent.h

@@ -4,6 +4,7 @@
 #include "Ref.h"
 #include "AIStateMachine.h"
 #include "AIMessage.h"
+#include "ScriptTarget.h"
 
 namespace gameplay
 {
@@ -18,7 +19,7 @@ class Node;
  * such as state machines. By default, an AIAgent has an empty state 
  * machine.
  */
-class AIAgent : public Ref
+class AIAgent : public Ref, public ScriptTarget
 {
     friend class Node;
     friend class AIController;

+ 1 - 1
gameplay/src/AIMessage.h

@@ -56,7 +56,7 @@ public:
      *
      * @return A new AIMessage.
      */
-    static AIMessage* create(unsigned int id, const char* sender, const char* receiver, unsigned int paramterCount);
+    static AIMessage* create(unsigned int id, const char* sender, const char* receiver, unsigned int parameterCount);
 
     /**
      * Returns the message ID.

+ 6 - 3
gameplay/src/AIState.cpp

@@ -10,6 +10,9 @@ AIState* AIState::_empty = NULL;
 AIState::AIState(const char* id)
     : _id(id), _listener(NULL)
 {
+    addEvent("enter", "<AIAgent><AIState>");
+    addEvent("exit", "<AIAgent><AIState>");
+    addEvent("update", "<AIAgent><AIState>f");
 }
 
 AIState::~AIState()
@@ -36,7 +39,7 @@ void AIState::enter(AIStateMachine* stateMachine)
     if (_listener)
         _listener->stateEnter(stateMachine->getAgent(), this);
 
-    // TODO: Fire script event
+    fireEvent<void>("enter", stateMachine->getAgent(), this);
 }
 
 void AIState::exit(AIStateMachine* stateMachine)
@@ -44,7 +47,7 @@ void AIState::exit(AIStateMachine* stateMachine)
     if (_listener)
         _listener->stateExit(stateMachine->getAgent(), this);
 
-    // TODO: Fire script event
+    fireEvent<void>("exit", stateMachine->getAgent(), this);
 }
 
 void AIState::update(AIStateMachine* stateMachine, float elapsedTime)
@@ -52,7 +55,7 @@ void AIState::update(AIStateMachine* stateMachine, float elapsedTime)
     if (_listener)
         _listener->stateUpdate(stateMachine->getAgent(), this, elapsedTime);
 
-    // TODO: Fire script event
+    fireEvent<void>("update", stateMachine->getAgent(), this);
 }
 
 AIState::Listener::~Listener()

+ 2 - 1
gameplay/src/AIState.h

@@ -2,6 +2,7 @@
 #define AISTATE_H_
 
 #include "Ref.h"
+#include "ScriptTarget.h"
 
 namespace gameplay
 {
@@ -18,7 +19,7 @@ class AIStateMachine;
  *
  * 
  */
-class AIState : public Ref
+class AIState : public Ref, public ScriptTarget
 {
     friend class AIStateMachine;
 

+ 15 - 3
gameplay/src/AnimationClip.cpp

@@ -4,7 +4,7 @@
 #include "AnimationTarget.h"
 #include "Game.h"
 #include "Quaternion.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 
 namespace gameplay
 {
@@ -13,7 +13,7 @@ AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long
     : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _duration(_endTime - _startTime), 
       _stateBits(0x00), _repeatCount(1.0f), _activeDuration(_duration * _repeatCount), _speed(1.0f), _timeStarted(0), 
       _elapsedTime(0), _crossFadeToClip(NULL), _crossFadeOutElapsed(0), _crossFadeOutDuration(0), _blendWeight(1.0f), 
-      _beginListeners(NULL), _endListeners(NULL), _listeners(NULL), _scriptListeners(NULL), _listenerItr(NULL)
+      _beginListeners(NULL), _endListeners(NULL), _listeners(NULL), _listenerItr(NULL), _scriptListeners(NULL)
 {
     GP_ASSERT(_animation);
     GP_ASSERT(0 <= startTime && startTime <= _animation->_duration && 0 <= endTime && endTime <= _animation->_duration);
@@ -534,7 +534,7 @@ void AnimationClip::onBegin()
         _elapsedTime = (Game::getGameTime() - _timeStarted) * _speed;
 
         if (_listeners)
-            *_listenerItr = _listeners->begin(); 
+            *_listenerItr = _listeners->begin();
     }
     else
     {
@@ -615,4 +615,16 @@ AnimationClip* AnimationClip::clone(Animation* animation) const
     return newClip;
 }
 
+AnimationClip::ScriptListener::ScriptListener(const std::string& function)
+{
+    // Store the function name.
+    this->function = Game::getInstance()->getScriptController()->loadUrl(function.c_str());
+}
+
+void AnimationClip::ScriptListener::animationEvent(AnimationClip* clip, EventType type)
+{
+    Game::getInstance()->getScriptController()->executeFunction<void>(function.c_str(), "<AnimationClip>[AnimationClip::Listener::EventType]", clip, type);
+}
+
+
 }

+ 19 - 0
gameplay/src/AnimationClip.h

@@ -302,6 +302,25 @@ private:
         unsigned long _eventTime;   // The time at which the listener will be called back at during the playback of the AnimationClip.
     };
 
+    /**
+     * Listener implementation for script callbacks.
+     */
+    struct ScriptListener : public AnimationClip::Listener
+    {
+        /**
+         * Constructor.
+         */
+        ScriptListener(const std::string& function);
+
+        /**
+         * @see AnimationClip::Listener::animationEvent
+         */
+        void animationEvent(AnimationClip* clip, EventType type);
+
+        /** The function to call back when an animation event occurs. */
+        std::string function;
+    };
+
     /**
      * Constructor.
      */

+ 4 - 21
gameplay/src/Control.cpp

@@ -1,16 +1,16 @@
 #include "Base.h"
 #include "Game.h"
 #include "Control.h"
-#include "ScriptListener.h"
 
 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), _scriptListeners(NULL),
+    _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(true), _listeners(NULL),
     _contactIndex(INVALID_CONTACT_INDEX), _styleOverridden(false), _skin(NULL)
 {
+    addEvent("controlEvent", "<Control>[Control::Listener::EventType]");
 }
 
 Control::~Control()
@@ -25,15 +25,6 @@ Control::~Control()
         SAFE_DELETE(_listeners);
     }
 
-    if (_scriptListeners)
-    {
-        for (unsigned int i = 0; i < _scriptListeners->size(); i++)
-        {
-            SAFE_DELETE((*_scriptListeners)[i]);
-        }
-        SAFE_DELETE(_scriptListeners);
-    }
-
     if (_styleOverridden)
     {
         SAFE_DELETE(_style);
@@ -683,16 +674,6 @@ void Control::addListener(Control::Listener* listener, int eventFlags)
     }
 }
 
-void Control::addListener(const char* function, int eventFlags)
-{
-    if (!_scriptListeners)
-        _scriptListeners = new std::vector<ScriptListener*>();
-
-    ScriptListener* listener = new ScriptListener(function);
-    _scriptListeners->push_back(listener);
-    addListener(listener, eventFlags);
-}
-
 void Control::addSpecificListener(Control::Listener* listener, Listener::EventType eventType)
 {
     GP_ASSERT(listener);
@@ -808,6 +789,8 @@ void Control::notifyListeners(Listener::EventType eventType)
             }
         }
     }
+
+    fireEvent<void>("controlEvent", this, eventType);
 }
 
 void Control::update(const Control* container, const Vector2& offset)

+ 2 - 22
gameplay/src/Control.h

@@ -10,16 +10,15 @@
 #include "Touch.h"
 #include "Keyboard.h"
 #include "Mouse.h"
+#include "ScriptTarget.h"
 
 namespace gameplay
 {
 
-class ScriptListener;
-
 /**
  * Base class for UI controls.
  */
-class Control : public Ref, public AnimationTarget
+class Control : public Ref, public AnimationTarget, public ScriptTarget
 {
     friend class Form;
     friend class Container;
@@ -721,20 +720,6 @@ public:
      */
     virtual void addListener(Control::Listener* listener, int eventFlags);
 
-    /**
-     * Add a listener to be notified of specific events affecting
-     * this control.  Event types can be OR'ed together.
-     * E.g. To listen to touch-press and touch-release events,
-     * pass <code>Control::Listener::TOUCH | Control::Listener::RELEASE</code>
-     * as the second parameter.
-     * 
-     * Note: the given Lua function must have the same function signature as Control::Listener::controlEvent.
-     *
-     * @param function The name of the Lua script function to add as a listener callback.
-     * @param eventFlags The events to listen for.
-     */
-    virtual void addListener(const char* function, int eventFlags);
-
     /**
      * @see AnimationTarget::getAnimationPropertyComponentCount
      */
@@ -979,11 +964,6 @@ protected:
      * Listeners map of EventType's to a list of Listeners.
      */
     std::map<Listener::EventType, std::list<Listener*>*>* _listeners;
-
-    /**
-     * Script listener objects.
-     */
-    std::vector<ScriptListener*>* _scriptListeners;
     
     /**
      * The Control's Theme::Style.

+ 10 - 1
gameplay/src/Game.cpp

@@ -5,7 +5,6 @@
 #include "FileSystem.h"
 #include "FrameBuffer.h"
 #include "SceneLoader.h"
-#include "ScriptListener.h"
 
 GLenum __gl_error_code = GL_NO_ERROR;
 ALenum __al_error_code = AL_NO_ERROR;
@@ -471,6 +470,16 @@ void Game::fireTimeEvents(double frameTime)
     }
 }
 
+Game::ScriptListener::ScriptListener(const char* url)
+{
+    function = Game::getInstance()->getScriptController()->loadUrl(url);
+}
+
+void Game::ScriptListener::timeEvent(long timeDiff, void* cookie)
+{
+    Game::getInstance()->getScriptController()->executeFunction<void>(function.c_str(), "l", timeDiff);
+}
+
 Game::TimeEvent::TimeEvent(double time, TimeListener* timeListener, void* cookie)
     : time(time), listener(timeListener), cookie(cookie)
 {

+ 19 - 0
gameplay/src/Game.h

@@ -466,6 +466,25 @@ protected:
 
 private:
 
+    /**
+     * Allows time listener interaction from Lua scripts.
+     */
+    struct ScriptListener : public TimeListener
+    {
+        /**
+         * Constructor.
+         */
+        ScriptListener(const char* url);
+
+        /**
+         * @see TimeListener#timeEvent(long, void*)
+         */
+        void timeEvent(long timeDiff, void* cookie);
+
+        /** Holds the name of the Lua script function to call back. */
+        std::string function;
+    };
+
     /**
      * TimeEvent represents the event that is sent to TimeListeners as a result of calling Game::schedule().
      */

+ 17 - 3
gameplay/src/PhysicsCollisionObject.cpp

@@ -3,7 +3,7 @@
 #include "PhysicsController.h"
 #include "Game.h"
 #include "Node.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 
 namespace gameplay
 {
@@ -139,10 +139,10 @@ void PhysicsCollisionObject::removeCollisionListener(const char* function, Physi
     if (!_scriptListeners)
         return;
 
-    std::string functionStr = function;
+    std::string url = function;
     for (unsigned int i = 0; i < _scriptListeners->size(); i++)
     {
-        if ((*_scriptListeners)[i]->_function == functionStr)
+        if ((*_scriptListeners)[i]->url == url)
         {
             removeCollisionListener((*_scriptListeners)[i], object);
             SAFE_DELETE((*_scriptListeners)[i]);
@@ -251,4 +251,18 @@ void PhysicsCollisionObject::PhysicsMotionState::updateTransformFromNode() const
     }
 }
 
+PhysicsCollisionObject::ScriptListener::ScriptListener(const char* url)
+{
+    this->url = url;
+    function = Game::getInstance()->getScriptController()->loadUrl(url);
+}
+
+void PhysicsCollisionObject::ScriptListener::collisionEvent(PhysicsCollisionObject::CollisionListener::EventType type,
+    const PhysicsCollisionObject::CollisionPair& collisionPair, const Vector3& contactPointA, const Vector3& contactPointB)
+{
+    Game::getInstance()->getScriptController()->executeFunction<void>(function.c_str(), 
+        "[PhysicsCollisionObject::CollisionListener::EventType]<PhysicsCollisionObject::CollisionPair><Vector3><Vector3>",
+        type, &collisionPair, &contactPointA, &contactPointB);
+}
+
 }

+ 22 - 2
gameplay/src/PhysicsCollisionObject.h

@@ -8,7 +8,6 @@ namespace gameplay
 {
 
 class Node;
-class ScriptListener;
 
 /**
  * Base class for all gameplay physics objects that support collision events.
@@ -231,6 +230,27 @@ public:
 
 
 protected:
+    /**
+     * Handles collision event callbacks to Lua script functions.
+     */
+    struct ScriptListener : public CollisionListener
+    {
+        /**
+         * Constructor.
+         */
+        ScriptListener(const char* url);
+
+        /**
+         * @see PhysicsColliionObject::CollisionListener
+         */
+        void collisionEvent(PhysicsCollisionObject::CollisionListener::EventType type, const PhysicsCollisionObject::CollisionPair& collisionPair,
+                                    const Vector3& contactPointA, const Vector3& contactPointB);
+
+        /** The URL to the Lua script function to use as the callback. */
+        std::string url;
+        /** The name of the Lua script function to use as the callback. */
+        std::string function;
+    };
 
     /**
      * Interface between GamePlay and Bullet to keep object transforms synchronized properly.
@@ -311,7 +331,7 @@ protected:
     bool _enabled;
 
     /**
-     * Lua script collision listeners.
+     * The list of script listeners.
      */
     std::vector<ScriptListener*>* _scriptListeners;
 };

+ 12 - 43
gameplay/src/PhysicsController.cpp

@@ -5,7 +5,6 @@
 #include "Game.h"
 #include "MeshPart.h"
 #include "Bundle.h"
-#include "ScriptListener.h"
 
 #include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
 
@@ -24,10 +23,12 @@ PhysicsController::PhysicsController()
   : _isUpdating(false), _collisionConfiguration(NULL), _dispatcher(NULL),
     _overlappingPairCache(NULL), _solver(NULL), _world(NULL), _ghostPairCallback(NULL),
     _debugDrawer(NULL), _status(PhysicsController::Listener::DEACTIVATED), _listeners(NULL),
-    _gravity(btScalar(0.0), btScalar(-9.8), btScalar(0.0)), _collisionCallback(NULL), _scriptListeners(NULL)
+    _gravity(btScalar(0.0), btScalar(-9.8), btScalar(0.0)), _collisionCallback(NULL)
 {
     // Default gravity is 9.8 along the negative Y axis.
     _collisionCallback = new CollisionCallback(this);
+
+    addEvent("statusEvent", "[PhysicsController::Listener::EventType]");
 }
 
 PhysicsController::~PhysicsController()
@@ -36,15 +37,6 @@ PhysicsController::~PhysicsController()
     SAFE_DELETE(_ghostPairCallback);
     SAFE_DELETE(_debugDrawer);
     SAFE_DELETE(_listeners);
-
-    if (_scriptListeners)
-    {
-        for (unsigned int i = 0; i < _scriptListeners->size(); i++)
-        {
-            SAFE_DELETE((*_scriptListeners)[i]);
-        }
-        SAFE_DELETE(_scriptListeners);
-    }
 }
 
 void PhysicsController::addStatusListener(Listener* listener)
@@ -72,34 +64,6 @@ void PhysicsController::removeStatusListener(Listener* listener)
     }
 }
 
-void PhysicsController::addStatusListener(const char* function)
-{
-    if (!_scriptListeners)
-        _scriptListeners = new std::vector<ScriptListener*>();
-
-    ScriptListener* listener = new ScriptListener(function);
-    _scriptListeners->push_back(listener);
-    addStatusListener(listener);
-}
-
-void PhysicsController::removeStatusListener(const char* function)
-{
-    if (!_scriptListeners)
-        return;
-
-    std::string functionStr = function;
-    for (unsigned int i = 0; i < _scriptListeners->size(); i++)
-    {
-        if ((*_scriptListeners)[i]->_function == functionStr)
-        {
-            removeStatusListener((*_scriptListeners)[i]);
-            SAFE_DELETE((*_scriptListeners)[i]);
-            _scriptListeners->erase(_scriptListeners->begin() + i);
-            return;
-        }
-    }
-}
-
 PhysicsFixedConstraint* PhysicsController::createFixedConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
 {
     checkConstraintRigidBodies(a, b);
@@ -512,7 +476,7 @@ void PhysicsController::update(float elapsedTime)
     _world->stepSimulation(elapsedTime * 0.001f, 10);
 
     // If we have status listeners, then check if our status has changed.
-    if (_listeners)
+    if (_listeners || _callbacks["statusEvent"])
     {
         Listener::EventType oldStatus = _status;
 
@@ -548,11 +512,16 @@ void PhysicsController::update(float elapsedTime)
         // If the status has changed, notify our listeners.
         if (oldStatus != _status)
         {
-            for (unsigned int k = 0; k < _listeners->size(); k++)
+            if (_listeners)
             {
-                GP_ASSERT((*_listeners)[k]);
-                (*_listeners)[k]->statusEvent(_status);
+                for (unsigned int k = 0; k < _listeners->size(); k++)
+                {
+                    GP_ASSERT((*_listeners)[k]);
+                    (*_listeners)[k]->statusEvent(_status);
+                }
             }
+
+            fireEvent<void>("statusEvent", _status);
         }
     }
 

+ 2 - 18
gameplay/src/PhysicsController.h

@@ -9,6 +9,7 @@
 #include "PhysicsSpringConstraint.h"
 #include "PhysicsCollisionObject.h"
 #include "MeshBatch.h"
+#include "ScriptTarget.h"
 
 namespace gameplay
 {
@@ -18,7 +19,7 @@ class ScriptListener;
 /**
  * Defines a class for controlling game physics.
  */
-class PhysicsController
+class PhysicsController : public ScriptTarget
 {
     friend class Game;
     friend class PhysicsConstraint;
@@ -153,22 +154,6 @@ public:
      */
     void removeStatusListener(Listener* listener);
 
-    /**
-     * Adds a listener to the physics controller.
-     * 
-     * Note: the given Lua function must have the same function signature as PhysicsController::Listener::statusEvent.
-     * 
-     * @param function The Lua script function to use as the listener callback.
-     */
-    void addStatusListener(const char* function);
-
-    /**
-     * Removes a listener to the physics controller.
-     * 
-     * @param function The Lua script function (used as a listener callback) to remove.
-     */
-    void removeStatusListener(const char* function);
-
     /**
      * Creates a fixed constraint.
      * 
@@ -565,7 +550,6 @@ private:
     Vector3 _gravity;
     std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo> _collisionStatus;
     CollisionCallback* _collisionCallback;
-    std::vector<ScriptListener*>* _scriptListeners;
 };
 
 }

+ 132 - 6
gameplay/src/ScriptController.cpp

@@ -41,6 +41,8 @@
 namespace gameplay
 {
 
+extern void splitURL(const std::string& url, std::string* file, std::string* id);
+
 void ScriptUtil::registerLibrary(const char* name, const luaL_Reg* functions)
 {
     ScriptController* sc = Game::getInstance()->getScriptController();
@@ -328,13 +330,41 @@ bool ScriptUtil::luaCheckBool(lua_State* state, int n)
 }
 
 
-void ScriptController::loadScript(const char* path)
+void ScriptController::loadScript(const char* path, bool forceReload)
+{
+    std::set<std::string>::iterator iter = _loadedScripts.find(path);
+    if (iter == _loadedScripts.end() || forceReload)
+    {
+        const char* scriptContents = FileSystem::readAll(path);
+        if (luaL_dostring(_lua, scriptContents))
+            GP_ERROR("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1));
+
+        SAFE_DELETE_ARRAY(scriptContents);
+
+        if (iter == _loadedScripts.end())
+            _loadedScripts.insert(path);
+    }
+}
+
+std::string ScriptController::loadUrl(const char* url)
 {
-    const char* scriptContents = FileSystem::readAll(path);
-    if (luaL_dostring(_lua, scriptContents))
-        GP_ERROR("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1));
+    std::string file;
+    std::string id;
+    splitURL(url, &file, &id);
+
+    // Make sure the function isn't empty.
+    if (id.size() <= 0)
+    {
+        GP_ERROR("Got an empty function name when parsing function url '%s'.", url);
+        return std::string();
+    }
 
-    SAFE_DELETE_ARRAY(scriptContents);
+    // Ensure the script is loaded.
+    if (file.size() > 0)
+        Game::getInstance()->getScriptController()->loadScript(file.c_str());
+
+    // Return the function name.
+    return id;
 }
 
 bool ScriptController::getBool(const char* name)
@@ -718,7 +748,6 @@ ScriptController::ScriptCallback ScriptController::toCallback(const char* name)
         return ScriptController::INVALID_CALLBACK;
 }
 
-
 // Helper macros.
 #define SCRIPT_EXECUTE_FUNCTION_NO_PARAM(type, checkfunc) \
     executeFunctionHelper(1, func, NULL, NULL); \
@@ -735,6 +764,12 @@ ScriptController::ScriptCallback ScriptController::toCallback(const char* name)
     va_end(list); \
     return value;
 
+#define SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(type, checkfunc) \
+    executeFunctionHelper(1, func, args, list); \
+    type value = (type)checkfunc(_lua, -1); \
+    lua_pop(_lua, -1); \
+    return value;
+
 template<> void ScriptController::executeFunction<void>(const char* func)
 {
     executeFunctionHelper(0, func, NULL, NULL);
@@ -800,6 +835,7 @@ template<> std::string ScriptController::executeFunction<std::string>(const char
     SCRIPT_EXECUTE_FUNCTION_NO_PARAM(std::string, luaL_checkstring);
 }
 
+/** Template specialization. */
 template<> void ScriptController::executeFunction<void>(const char* func, const char* args, ...)
 {
     va_list list;
@@ -808,64 +844,154 @@ template<> void ScriptController::executeFunction<void>(const char* func, const
     va_end(list);
 }
 
+/** Template specialization. */
 template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(bool, ScriptUtil::luaCheckBool);
 }
 
+/** Template specialization. */
 template<> char ScriptController::executeFunction<char>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(char, luaL_checkint);
 }
 
+/** Template specialization. */
 template<> short ScriptController::executeFunction<short>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(short, luaL_checkint);
 }
 
+/** Template specialization. */
 template<> int ScriptController::executeFunction<int>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(int, luaL_checkint);
 }
 
+/** Template specialization. */
 template<> long ScriptController::executeFunction<long>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(long, luaL_checklong);
 }
 
+/** Template specialization. */
 template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned char, luaL_checkunsigned);
 }
 
+/** Template specialization. */
 template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned short, luaL_checkunsigned);
 }
 
+/** Template specialization. */
 template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned int, luaL_checkunsigned);
 }
 
+/** Template specialization. */
 template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned long, luaL_checkunsigned);
 }
 
+/** Template specialization. */
 template<> float ScriptController::executeFunction<float>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(float, luaL_checknumber);
 }
 
+/** Template specialization. */
 template<> double ScriptController::executeFunction<double>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(double, luaL_checknumber);
 }
 
+/** Template specialization. */
 template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, ...)
 {
     SCRIPT_EXECUTE_FUNCTION_PARAM(std::string, luaL_checkstring);
 }
 
+/** Template specialization. */
+template<> void ScriptController::executeFunction<void>(const char* func, const char* args, va_list* list)
+{
+    executeFunctionHelper(0, func, args, list);
+}
+
+/** Template specialization. */
+template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(bool, ScriptUtil::luaCheckBool);
+}
+
+/** Template specialization. */
+template<> char ScriptController::executeFunction<char>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(char, luaL_checkint);
+}
+
+/** Template specialization. */
+template<> short ScriptController::executeFunction<short>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(short, luaL_checkint);
+}
+
+/** Template specialization. */
+template<> int ScriptController::executeFunction<int>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(int, luaL_checkint);
+}
+
+/** Template specialization. */
+template<> long ScriptController::executeFunction<long>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(long, luaL_checklong);
+}
+
+/** Template specialization. */
+template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned char, luaL_checkunsigned);
+}
+
+/** Template specialization. */
+template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned short, luaL_checkunsigned);
+}
+
+/** Template specialization. */
+template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned int, luaL_checkunsigned);
+}
+
+/** Template specialization. */
+template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned long, luaL_checkunsigned);
+}
+
+/** Template specialization. */
+template<> float ScriptController::executeFunction<float>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(float, luaL_checknumber);
+}
+
+/** Template specialization. */
+template<> double ScriptController::executeFunction<double>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(double, luaL_checknumber);
+}
+
+/** Template specialization. */
+template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, va_list* list)
+{
+    SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(std::string, luaL_checkstring);
+}
+
 }

+ 63 - 1
gameplay/src/ScriptController.h

@@ -236,8 +236,17 @@ public:
      * Loads the given script file and executes its global code.
      * 
      * @param path The path to the script.
+     * @param forceReload Whether the script should be reloaded if it has already been loaded.
      */
-    void loadScript(const char* path);
+    void loadScript(const char* path, bool forceReload = false);
+
+    /**
+     * Given a URL, loads the referenced file and returns the referenced function name.
+     * 
+     * @param url The url to load.
+     * @return The function that the URL references.
+     */
+    std::string loadUrl(const char* url);
 
     /**
      * Calls the specifed no-parameter Lua function.
@@ -271,6 +280,31 @@ public:
      */
     template<typename T> T executeFunction(const char* func, const char* args, ...);
 
+    /**
+     * Calls the specifed Lua function using the given parameters.
+     * 
+     * @param func The name of the function to call.
+     * @param args The argument signature of the function. Of the form 'xxx', where each 'x' is a parameter type and must be one of:
+     *      - 'b' - bool
+     *      - 'c' - char
+     *      - 'h' - short
+     *      - 'i' - int
+     *      - 'l' - long
+     *      - 'f' - float
+     *      - 'd' - double
+     *      - 'ui' - unsigned int
+     *      - 'ul' - unsigned long
+     *      - 'uc' - unsigned char
+     *      - 'uh' - unsigned short
+     *      - 's' - string
+     *      - 'p' - pointer
+     *      - '<object-type>' - a <b>pointer</b> to an object of the given type (where the qualified type name is enclosed by angle brackets).
+     *      - '[enum-type]' - an enumerated value of the given type (where the qualified type name is enclosed by square brackets).
+     * @param list The variable argument list containing the function's parameters.
+     * @return The return value of the executed Lua function.
+     */
+    template<typename T> T executeFunction(const char* func, const char* args, va_list* list);
+
     /**
      * Gets the global boolean script variable with the given name.
      * 
@@ -687,6 +721,7 @@ private:
     unsigned int _returnCount;
     std::map<std::string, std::vector<std::string> > _hierarchy;
     std::string* _callbacks[CALLBACK_COUNT];
+    std::set<std::string> _loadedScripts;
 };
 
 /** Template specialization. */
@@ -743,6 +778,33 @@ template<> double ScriptController::executeFunction<double>(const char* func, co
 /** Template specialization. */
 template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, ...);
 
+/** Template specialization. */
+template<> void ScriptController::executeFunction<void>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> char ScriptController::executeFunction<char>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> short ScriptController::executeFunction<short>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> int ScriptController::executeFunction<int>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> long ScriptController::executeFunction<long>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> float ScriptController::executeFunction<float>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> double ScriptController::executeFunction<double>(const char* func, const char* args, va_list* list);
+/** Template specialization. */
+template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, va_list* list);
+
 }
 
 #include "ScriptController.inl"

+ 9 - 0
gameplay/src/ScriptController.inl

@@ -150,6 +150,15 @@ template<typename T> T ScriptController::executeFunction(const char* func, const
     return value;
 }
 
+template<typename T> T ScriptController::executeFunction(const char* func, const char* args, va_list* list)
+{
+    executeFunctionHelper(1, func, args, list);
+
+    T value = (T)((ScriptUtil::LuaObject*)lua_touserdata(_lua, -1))->instance;
+    lua_pop(_lua, -1);
+    return value;
+}
+
 template<typename T>T* ScriptController::getObjectPointer(const char* type, const char* name)
 {
     lua_getglobal(_lua, name);

+ 0 - 56
gameplay/src/ScriptListener.cpp

@@ -1,56 +0,0 @@
-#include "Base.h"
-#include "ScriptController.h"
-#include "ScriptListener.h"
-
-namespace gameplay
-{
-
-static const char* SL_ANIMATION_ARGS = "<AnimationClip>[AnimationClip::Listener::EventType]";
-static const char* SL_PHYSICS_COLLISION_ARGS = "[PhysicsCollisionObject::CollisionListener::EventType]<PhysicsCollisionObject::CollisionPair><Vector3><Vector3>";
-static const char* SL_TRANSFORM_ARGS = "<Transform>l";
-static const char* SL_PHYSICS_STATUS_ARGS = "[PhysicsController::Listener::EventType]";
-static const char* SL_CONTROL_ARGS = "<Control>[Control::Listener::EventType]";
-static const char* SL_TIME_ARGS = "l";
-
-void ScriptListener::animationEvent(AnimationClip* clip, AnimationClip::Listener::EventType type)
-{
-    _sc->executeFunction<void>(_function.c_str(), SL_ANIMATION_ARGS, clip, type);
-}
-
-void ScriptListener::collisionEvent(PhysicsCollisionObject::CollisionListener::EventType type,
-    const PhysicsCollisionObject::CollisionPair& collisionPair, const Vector3& contactPointA, const Vector3& contactPointB)
-{
-    _sc->executeFunction<void>(_function.c_str(), SL_PHYSICS_COLLISION_ARGS, type, &collisionPair, &contactPointA, &contactPointB);
-}
-
-void ScriptListener::transformChanged(Transform* transform, long cookie)
-{
-    _sc->executeFunction<void>(_function.c_str(), SL_TRANSFORM_ARGS, transform, cookie);
-}
-
-void ScriptListener::statusEvent(PhysicsController::Listener::EventType type)
-{
-    _sc->executeFunction<void>(_function.c_str(), SL_PHYSICS_STATUS_ARGS, type);
-}
-
-void ScriptListener::controlEvent(Control* control, Control::Listener::EventType evt)
-{
-    _sc->executeFunction<void>(_function.c_str(), SL_CONTROL_ARGS, control, evt);
-}
-
-void ScriptListener::timeEvent(long timeDiff, void* cookie)
-{
-    _sc->executeFunction<void>(_function.c_str(), SL_TIME_ARGS, timeDiff);
-}
-
-ScriptListener::ScriptListener(const char* function)
-{
-    _function = function ? function : "";
-    _sc = Game::getInstance()->getScriptController();
-
-    GP_ASSERT(_function.size() > 0);
-    GP_ASSERT(_sc);
-}
-
-
-}

+ 0 - 66
gameplay/src/ScriptListener.h

@@ -1,66 +0,0 @@
-#ifndef SCRIPTLISTENER_H_
-#define SCRIPTLISTENER_H_
-
-#include "AnimationClip.h"
-#include "Control.h"
-#include "PhysicsCollisionObject.h"
-#include "PhysicsController.h"
-#include "Transform.h"
-#include "TimeListener.h"
-
-namespace gameplay
-{
-
-/**
- * Used to bind Lua script functions as listeners
- * for any listener interface within gameplay.
- * 
- * @script{ignore}
- */
-class ScriptListener : public AnimationClip::Listener, public PhysicsCollisionObject::CollisionListener,
-    public Transform::Listener, public PhysicsController::Listener, public Control::Listener, public TimeListener
-{
-    friend class AnimationClip;
-    friend class Control;
-    friend class Game;
-    friend class PhysicsCollisionObject;
-    friend class PhysicsController;
-    friend class Transform;
-
-public:
-    /** @see AnimationClip::Listener */
-    void animationEvent(AnimationClip* clip, AnimationClip::Listener::EventType type);
-        
-    /** @see PhysicsCollisionObject::CollisionListener */
-    void collisionEvent(PhysicsCollisionObject::CollisionListener::EventType type,
-                                const PhysicsCollisionObject::CollisionPair& collisionPair,
-                                const Vector3& contactPointA = Vector3::zero(),
-                                const Vector3& contactPointB = Vector3::zero());
-
-    /** @see Transform::Listener */
-    void transformChanged(Transform* transform, long cookie);
-
-    /** @see PhysicsController::Listener */
-    void statusEvent(PhysicsController::Listener::EventType type);
-
-    /** @see Control::Listener */
-    void controlEvent(Control* control, Control::Listener::EventType evt);
-
-    /** @see TimeListener */
-    void timeEvent(long timeDiff, void* cookie);
-
-private:
-    /**
-     * Constructor.
-     */
-    ScriptListener(const char* function);
-
-    /** Holds the name of the Lua function to be called back. */
-    std::string _function;
-    /** Holds the global script controller. */
-    ScriptController* _sc;
-};
-
-}
-
-#endif

+ 146 - 0
gameplay/src/ScriptTarget.cpp

@@ -0,0 +1,146 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "ScriptTarget.h"
+
+namespace gameplay
+{
+
+extern void splitURL(const std::string& url, std::string* file, std::string* id);
+
+ScriptTarget::~ScriptTarget()
+{
+    std::map<std::string, std::vector<Callback>* >::iterator iter = _callbacks.begin();
+    for (; iter != _callbacks.end(); iter++)
+    {
+        SAFE_DELETE(iter->second);
+    }
+}
+
+template<> void ScriptTarget::fireEvent<void>(const char* eventName, ...)
+{
+    va_list list;
+    va_start(list, eventName);
+
+    std::map<std::string, std::vector<Callback>* >::iterator iter = _callbacks.find(eventName);
+    if (iter != _callbacks.end() && iter->second != NULL)
+    {
+        ScriptController* sc = Game::getInstance()->getScriptController();
+
+        if (_events[eventName].size() > 0)
+        {
+            for (unsigned int i = 0; i < iter->second->size(); i++)
+            {
+                sc->executeFunction<void>((*iter->second)[i].function.c_str(), _events[eventName].c_str(), &list);
+            }
+        }
+        else
+        {
+            for (unsigned int i = 0; i < iter->second->size(); i++)
+            {
+                sc->executeFunction<void>((*iter->second)[i].function.c_str(), _events[eventName].c_str());
+            }
+        }
+    }
+
+    va_end(list);
+}
+
+template<> bool ScriptTarget::fireEvent<bool>(const char* eventName, ...)
+{
+    va_list list;
+    va_start(list, eventName);
+
+    std::map<std::string, std::vector<Callback>* >::iterator iter = _callbacks.find(eventName);
+    if (iter != _callbacks.end())
+    {
+        ScriptController* sc = Game::getInstance()->getScriptController();
+
+        if (_events[eventName].size() > 0)
+        {
+            for (unsigned int i = 0; i < iter->second->size(); i++)
+            {
+                if (sc->executeFunction<bool>((*iter->second)[i].function.c_str(), _events[eventName].c_str(), &list))
+                {
+                    va_end(list);
+                    return true;
+                }
+            }
+        }
+        else
+        {
+            for (unsigned int i = 0; i < iter->second->size(); i++)
+            {
+                if (sc->executeFunction<bool>((*iter->second)[i].function.c_str(), _events[eventName].c_str()))
+                {
+                    va_end(list);
+                    return true;
+                }
+            }
+        }
+    }
+
+    va_end(list);
+    return false;
+}
+
+void ScriptTarget::addCallback(const std::string& eventName, const std::string& function, void* data)
+{
+    std::map<std::string, std::vector<Callback>* >::iterator iter = _callbacks.find(eventName);
+    if (iter != _callbacks.end())
+    {
+        if (!iter->second)
+            iter->second = new std::vector<Callback>();
+
+        // Add the function to the list of callbacks.
+        std::string functionName = Game::getInstance()->getScriptController()->loadUrl(function.c_str());
+        iter->second->push_back(Callback(functionName, data));
+    }
+    else
+    {
+        GP_ERROR("Attempting to add a script callback for unsupported event '%s'.", eventName.c_str());
+    }
+}
+
+void ScriptTarget::removeCallback(const std::string& eventName, const std::string& function, void* data)
+{
+    std::map<std::string, std::vector<Callback>* >::iterator iter = _callbacks.find(eventName);
+    if (iter != _callbacks.end())
+    {
+        if (!iter->second)
+            return;
+
+        std::string file;
+        std::string id;
+        splitURL(function, &file, &id);
+
+        // Make sure the function isn't empty.
+        if (id.size() <= 0)
+            return;
+
+        // Remove the function from the list of callbacks.
+        for (unsigned int i = 0; i < iter->second->size(); i++)
+        {
+            if ((*iter->second)[i].data == data && (*iter->second)[i].function == id)
+            {
+                iter->second->erase(iter->second->begin() + i);
+                return;
+            }
+        }
+    }
+    else
+    {
+        GP_ERROR("Attempting to remove a script callback for unsupported event '%s'.", eventName.c_str());
+    }
+}
+
+void ScriptTarget::addEvent(const std::string& eventName, const char* argsString)
+{
+    _events[eventName] = (argsString ? argsString : "");
+    _callbacks[eventName] = NULL;
+}
+
+ScriptTarget::Callback::Callback(const std::string& function, void* data) : function(function), data(data)
+{
+}
+
+}

+ 89 - 0
gameplay/src/ScriptTarget.h

@@ -0,0 +1,89 @@
+#ifndef SCRIPTTARGET_H_
+#define SCRIPTTARGET_H_
+
+#include "Base.h"
+
+namespace gameplay
+{
+
+/**
+ * Generic base class for supporting script callbacks.
+ * 
+ * @script{ignore}
+ */
+class ScriptTarget
+{
+public:
+    /**
+     * Destructor.
+     */
+    virtual ~ScriptTarget();
+
+    /**
+     * Fires the event with the given event name and the given arguments.
+     * 
+     * @param eventName The name of the event.
+     */
+    template<typename T> T fireEvent(const char* eventName, ...);
+
+    /**
+     * Adds the given Lua script function as a callback for the given event.
+     * 
+     * @param eventName The name of the event.
+     * @param function The name of the Lua script function to call when the event is fired; can either be
+     *      just the name of a function (if the function's script file has already been loaded), or can be
+     *      a URL of the form scriptFile.lua#functionName.
+     * @param data Optional data for the callback.
+     */
+    virtual void addCallback(const std::string& eventName, const std::string& function, void* data = NULL);
+
+    /**
+     * Removes the given Lua script function as a callback for the given event.
+     * 
+     * @param eventName The name of the event.
+     * @param function The name of the Lua script function.
+     * @param data Optional data for the callback.
+     */
+    virtual void removeCallback(const std::string& eventName, const std::string& function, void* data = NULL);
+
+protected:
+    /**
+     * Adds the given event with the given Lua script parameter string ({@link ScriptController::executeFunction})
+     * as a supported event for this script target.
+     * 
+     * @param eventName The name of the event.
+     * @param argsString The argument string for the event.
+     */
+    void addEvent(const std::string& eventName, const char* argsString = NULL);
+
+    /** Used to store a script callbacks for given event. */
+    struct Callback
+    {
+        /** Constructor. */
+        Callback(const std::string& string, void* data);
+
+        /** Holds the Lua script callback function. */
+        std::string function;
+        /** Generic data storage. */
+        void* data;
+    };
+
+    /** Holds the supported events for this script target. */
+    std::map<std::string, std::string> _events;
+    /** Holds the callbacks for this script target's events. */
+    std::map<std::string, std::vector<Callback>*> _callbacks;
+};
+
+template<typename T> T ScriptTarget::fireEvent(const char* eventName, ...)
+{
+    GP_ERROR("Unsupported return type!");
+}
+
+/** Template specialization. */
+template<> void ScriptTarget::fireEvent<void>(const char* eventName, ...);
+/** Template specialization. */
+template<> bool ScriptTarget::fireEvent<bool>(const char* eventName, ...);
+
+}
+
+#endif

+ 9 - 41
gameplay/src/Transform.cpp

@@ -2,7 +2,6 @@
 #include "Transform.h"
 #include "Game.h"
 #include "Node.h"
-#include "ScriptListener.h"
 
 namespace gameplay
 {
@@ -11,44 +10,40 @@ int Transform::_suspendTransformChanged(0);
 std::vector<Transform*> Transform::_transformsChanged;
 
 Transform::Transform()
-    : _matrixDirtyBits(0), _listeners(NULL), _scriptListeners(NULL)
+    : _matrixDirtyBits(0), _listeners(NULL)
 {
     _targetType = AnimationTarget::TRANSFORM;
     _scale.set(Vector3::one());
+    addEvent("transformChanged", "<Transform>");
 }
 
 Transform::Transform(const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
-    : _matrixDirtyBits(0), _listeners(NULL), _scriptListeners(NULL)
+    : _matrixDirtyBits(0), _listeners(NULL)
 {
     _targetType = AnimationTarget::TRANSFORM;
     set(scale, rotation, translation);
+    addEvent("transformChanged", "<Transform>");
 }
 
 Transform::Transform(const Vector3& scale, const Matrix& rotation, const Vector3& translation)
-    : _matrixDirtyBits(0), _listeners(NULL), _scriptListeners(NULL)
+    : _matrixDirtyBits(0), _listeners(NULL)
 {
     _targetType = AnimationTarget::TRANSFORM;
     set(scale, rotation, translation);
+    addEvent("transformChanged", "<Transform>");
 }
 
 Transform::Transform(const Transform& copy)
-    : _matrixDirtyBits(0), _listeners(NULL), _scriptListeners(NULL)
+    : _matrixDirtyBits(0), _listeners(NULL)
 {
     _targetType = AnimationTarget::TRANSFORM;
     set(copy);
+    addEvent("transformChanged", "<Transform>");
 }
 
 Transform::~Transform()
 {
     SAFE_DELETE(_listeners);
-    if (_scriptListeners)
-    {
-        for (unsigned int i = 0; i < _scriptListeners->size(); i++)
-        {
-            SAFE_DELETE((*_scriptListeners)[i]);
-        }
-        SAFE_DELETE(_scriptListeners);
-    }
 }
 
 void Transform::suspendTransformChanged()
@@ -841,34 +836,6 @@ void Transform::removeListener(Transform::Listener* listener)
     }
 }
 
-void Transform::addListener(const char* function, long cookie)
-{
-    if (!_scriptListeners)
-        _scriptListeners = new std::vector<ScriptListener*>();
-
-    ScriptListener* listener = new ScriptListener(function);
-    _scriptListeners->push_back(listener);
-    addListener(listener, cookie);
-}
-
-void Transform::removeListener(const char* function)
-{
-    if (!_scriptListeners)
-        return;
-
-    std::string functionStr = function;
-    for (unsigned int i = 0; i < _scriptListeners->size(); i++)
-    {
-        if ((*_scriptListeners)[i]->_function == functionStr)
-        {
-            removeListener((*_scriptListeners)[i]);
-            SAFE_DELETE((*_scriptListeners)[i]);
-            _scriptListeners->erase(_scriptListeners->begin() + i);
-            return;
-        }
-    }
-}
-
 void Transform::transformChanged()
 {
     if (_listeners)
@@ -880,6 +847,7 @@ void Transform::transformChanged()
             l.listener->transformChanged(this, l.cookie);
         }
     }
+    fireEvent<void>("transformChanged", this);
 }
 
 void Transform::cloneInto(Transform* transform, NodeCloneContext &context) const

+ 2 - 23
gameplay/src/Transform.h

@@ -6,6 +6,7 @@
 #include "Quaternion.h"
 #include "Matrix.h"
 #include "AnimationTarget.h"
+#include "ScriptTarget.h"
 
 namespace gameplay
 {
@@ -28,7 +29,7 @@ class ScriptListener;
  * components using matrix.decompose(Vector3, Quaternion, Vector3) and then pass
  * those arguments to the appropriate constructor or set methods of Transform.
  */
-class Transform : public AnimationTarget
+class Transform : public AnimationTarget, public ScriptTarget
 {
 public:
 
@@ -735,23 +736,6 @@ public:
      * Removes a transform listener.
      */
     void removeListener(Transform::Listener* listener);
-
-    /**
-     * Adds a transform listener.
-     *
-     * Note: the given Lua function must match the function signature of Transform::Listener::transformChanged.
-     * 
-     * @param function The Lua script function to add as a listener callback.
-     * @param cookie An optional long value that is passed to the specified listener when it is called.
-     */
-    void addListener(const char* function, long cookie = 0);
-
-    /**
-     * Removes a transform listener.
-     * 
-     * @param function The Lua script function (used as a listener callback) to remove.
-     */
-    void removeListener(const char* function);
     
     /**
      * @see AnimationTarget::getAnimationPropertyComponentCount
@@ -860,11 +844,6 @@ protected:
      */
     std::list<TransformListener>* _listeners;
 
-    /**
-     * List of Lua script transform listeners.
-     */
-    std::vector<ScriptListener*>* _scriptListeners;
-
 private:
    
     void applyAnimationValueRotation(AnimationValue* value, unsigned int index, float blendWeight);

+ 1 - 1
gameplay/src/lua/lua_AnimationClip.cpp

@@ -8,7 +8,7 @@
 #include "Game.h"
 #include "Quaternion.h"
 #include "Ref.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "lua_AnimationClipListenerEventType.h"
 
 namespace gameplay

+ 1 - 1
gameplay/src/lua/lua_AnimationClipListener.cpp

@@ -8,7 +8,7 @@
 #include "Game.h"
 #include "Quaternion.h"
 #include "Ref.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "lua_AnimationClipListenerEventType.h"
 
 namespace gameplay

+ 0 - 1
gameplay/src/lua/lua_AudioListener.cpp

@@ -7,7 +7,6 @@
 #include "Base.h"
 #include "Game.h"
 #include "Node.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 

+ 0 - 1
gameplay/src/lua/lua_AudioSource.cpp

@@ -10,7 +10,6 @@
 #include "Game.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_AudioSourceState.h"
 #include "lua_CurveInterpolationType.h"

+ 0 - 16
gameplay/src/lua/lua_Button.cpp

@@ -10,7 +10,6 @@
 #include "Label.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
@@ -192,21 +191,6 @@ int lua_Button_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Button* instance = getInstance(state);
-                instance->Control::addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Button_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 1
gameplay/src/lua/lua_Camera.cpp

@@ -9,7 +9,6 @@
 #include "Node.h"
 #include "PhysicsController.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_CameraType.h"
 #include "lua_CurveInterpolationType.h"

+ 0 - 16
gameplay/src/lua/lua_CheckBox.cpp

@@ -11,7 +11,6 @@
 #include "Label.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
@@ -198,21 +197,6 @@ int lua_CheckBox_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                CheckBox* instance = getInstance(state);
-                instance->Button::Control::addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_CheckBox_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 16
gameplay/src/lua/lua_Container.cpp

@@ -17,7 +17,6 @@
 #include "Node.h"
 #include "RadioButton.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "Slider.h"
 #include "TextBox.h"
 #include "VerticalLayout.h"
@@ -254,21 +253,6 @@ int lua_Container_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Container* instance = getInstance(state);
-                instance->addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Container_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 16
gameplay/src/lua/lua_Control.cpp

@@ -8,7 +8,6 @@
 #include "Game.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
@@ -188,21 +187,6 @@ int lua_Control_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Control* instance = getInstance(state);
-                instance->addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Control_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 1
gameplay/src/lua/lua_ControlListener.cpp

@@ -8,7 +8,6 @@
 #include "Game.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"

+ 0 - 16
gameplay/src/lua/lua_Form.cpp

@@ -19,7 +19,6 @@
 #include "RadioButton.h"
 #include "Ref.h"
 #include "Scene.h"
-#include "ScriptListener.h"
 #include "Slider.h"
 #include "TextBox.h"
 #include "Theme.h"
@@ -262,21 +261,6 @@ int lua_Form_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Form* instance = getInstance(state);
-                instance->addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Form_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 1
gameplay/src/lua/lua_Game.cpp

@@ -8,7 +8,6 @@
 #include "Platform.h"
 #include "RenderState.h"
 #include "SceneLoader.h"
-#include "ScriptListener.h"
 #include "lua_GameClearFlags.h"
 #include "lua_GameState.h"
 #include "lua_GamepadGamepadEvent.h"

+ 0 - 5
gameplay/src/lua/lua_Global.cpp

@@ -12,7 +12,6 @@ void luaRegister_lua_Global()
     ScriptUtil::registerFunction("printError", lua__printError);
 
     std::map<std::string, std::vector<std::string> > hierarchy;
-    hierarchy["AnimationClip::Listener"].push_back("ScriptListener");
     hierarchy["AnimationTarget"].push_back("Button");
     hierarchy["AnimationTarget"].push_back("CheckBox");
     hierarchy["AnimationTarget"].push_back("Container");
@@ -39,7 +38,6 @@ void luaRegister_lua_Global()
     hierarchy["Control"].push_back("RadioButton");
     hierarchy["Control"].push_back("Slider");
     hierarchy["Control"].push_back("TextBox");
-    hierarchy["Control::Listener"].push_back("ScriptListener");
     hierarchy["Label"].push_back("Button");
     hierarchy["Label"].push_back("CheckBox");
     hierarchy["Label"].push_back("RadioButton");
@@ -52,13 +50,11 @@ void luaRegister_lua_Global()
     hierarchy["PhysicsCollisionObject"].push_back("PhysicsCharacter");
     hierarchy["PhysicsCollisionObject"].push_back("PhysicsGhostObject");
     hierarchy["PhysicsCollisionObject"].push_back("PhysicsRigidBody");
-    hierarchy["PhysicsCollisionObject::CollisionListener"].push_back("ScriptListener");
     hierarchy["PhysicsConstraint"].push_back("PhysicsFixedConstraint");
     hierarchy["PhysicsConstraint"].push_back("PhysicsGenericConstraint");
     hierarchy["PhysicsConstraint"].push_back("PhysicsHingeConstraint");
     hierarchy["PhysicsConstraint"].push_back("PhysicsSocketConstraint");
     hierarchy["PhysicsConstraint"].push_back("PhysicsSpringConstraint");
-    hierarchy["PhysicsController::Listener"].push_back("ScriptListener");
     hierarchy["PhysicsGenericConstraint"].push_back("PhysicsFixedConstraint");
     hierarchy["PhysicsGenericConstraint"].push_back("PhysicsSpringConstraint");
     hierarchy["PhysicsGhostObject"].push_back("PhysicsCharacter");
@@ -122,7 +118,6 @@ void luaRegister_lua_Global()
     hierarchy["Transform::Listener"].push_back("PhysicsCharacter");
     hierarchy["Transform::Listener"].push_back("PhysicsGhostObject");
     hierarchy["Transform::Listener"].push_back("PhysicsRigidBody");
-    hierarchy["Transform::Listener"].push_back("ScriptListener");
     ScriptUtil::setGlobalHierarchy(hierarchy);
 
     // Register enumeration AIMessage::ParameterType.

+ 0 - 38
gameplay/src/lua/lua_Joint.cpp

@@ -14,7 +14,6 @@
 #include "PhysicsRigidBody.h"
 #include "Ref.h"
 #include "Scene.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_NodeType.h"
@@ -273,17 +272,6 @@ int lua_Joint_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                Joint* instance = getInstance(state);
-                instance->addListener(param1);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Joint_addListener - Failed to match the given parameters to a valid function signature.");
@@ -308,21 +296,6 @@ int lua_Joint_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                long param2 = (long)luaL_checklong(state, 3);
-
-                Joint* instance = getInstance(state);
-                instance->addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Joint_addListener - Failed to match the given parameters to a valid function signature.");
@@ -3931,17 +3904,6 @@ int lua_Joint_removeListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                Joint* instance = getInstance(state);
-                instance->removeListener(param1);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Joint_removeListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 16
gameplay/src/lua/lua_Joystick.cpp

@@ -9,7 +9,6 @@
 #include "Joystick.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
@@ -195,21 +194,6 @@ int lua_Joystick_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Joystick* instance = getInstance(state);
-                instance->Control::addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Joystick_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 16
gameplay/src/lua/lua_Label.cpp

@@ -9,7 +9,6 @@
 #include "Label.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
@@ -192,21 +191,6 @@ int lua_Label_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Label* instance = getInstance(state);
-                instance->Control::addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Label_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 1
gameplay/src/lua/lua_MeshSkin.cpp

@@ -8,7 +8,6 @@
 #include "Joint.h"
 #include "MeshSkin.h"
 #include "Node.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 

+ 0 - 38
gameplay/src/lua/lua_Node.cpp

@@ -13,7 +13,6 @@
 #include "PhysicsRigidBody.h"
 #include "Ref.h"
 #include "Scene.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_NodeType.h"
@@ -272,17 +271,6 @@ int lua_Node_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                Node* instance = getInstance(state);
-                instance->addListener(param1);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Node_addListener - Failed to match the given parameters to a valid function signature.");
@@ -307,21 +295,6 @@ int lua_Node_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                long param2 = (long)luaL_checklong(state, 3);
-
-                Node* instance = getInstance(state);
-                instance->addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Node_addListener - Failed to match the given parameters to a valid function signature.");
@@ -3884,17 +3857,6 @@ int lua_Node_removeListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                Node* instance = getInstance(state);
-                instance->removeListener(param1);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Node_removeListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 1
gameplay/src/lua/lua_NodeCloneContext.cpp

@@ -13,7 +13,6 @@
 #include "PhysicsRigidBody.h"
 #include "Ref.h"
 #include "Scene.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_NodeType.h"

+ 1 - 1
gameplay/src/lua/lua_PhysicsCharacter.cpp

@@ -11,7 +11,7 @@
 #include "PhysicsController.h"
 #include "PhysicsGhostObject.h"
 #include "Scene.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"

+ 1 - 1
gameplay/src/lua/lua_PhysicsCollisionObject.cpp

@@ -6,7 +6,7 @@
 #include "Node.h"
 #include "PhysicsCollisionObject.h"
 #include "PhysicsController.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"
 #include "lua_PhysicsCollisionObjectType.h"
 #include "lua_PhysicsCollisionShapeType.h"

+ 1 - 1
gameplay/src/lua/lua_PhysicsCollisionObjectCollisionListener.cpp

@@ -6,7 +6,7 @@
 #include "Node.h"
 #include "PhysicsCollisionObject.h"
 #include "PhysicsController.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"
 #include "lua_PhysicsCollisionObjectType.h"
 #include "lua_PhysicsCollisionShapeType.h"

+ 1 - 1
gameplay/src/lua/lua_PhysicsCollisionObjectCollisionPair.cpp

@@ -6,7 +6,7 @@
 #include "Node.h"
 #include "PhysicsCollisionObject.h"
 #include "PhysicsController.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"
 #include "lua_PhysicsCollisionObjectType.h"
 #include "lua_PhysicsCollisionShapeType.h"

+ 0 - 23
gameplay/src/lua/lua_PhysicsController.cpp

@@ -8,7 +8,6 @@
 #include "PhysicsCharacter.h"
 #include "PhysicsController.h"
 #include "PhysicsRigidBody.h"
-#include "ScriptListener.h"
 #include "lua_PhysicsControllerListenerEventType.h"
 
 namespace gameplay
@@ -66,17 +65,6 @@ int lua_PhysicsController_addStatusListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                PhysicsController* instance = getInstance(state);
-                instance->addStatusListener(param1);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_PhysicsController_addStatusListener - Failed to match the given parameters to a valid function signature.");
@@ -1171,17 +1159,6 @@ int lua_PhysicsController_removeStatusListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                PhysicsController* instance = getInstance(state);
-                instance->removeStatusListener(param1);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_PhysicsController_removeStatusListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 1
gameplay/src/lua/lua_PhysicsControllerHitFilter.cpp

@@ -8,7 +8,6 @@
 #include "PhysicsCharacter.h"
 #include "PhysicsController.h"
 #include "PhysicsRigidBody.h"
-#include "ScriptListener.h"
 #include "lua_PhysicsControllerListenerEventType.h"
 
 namespace gameplay

+ 0 - 1
gameplay/src/lua/lua_PhysicsControllerHitResult.cpp

@@ -8,7 +8,6 @@
 #include "PhysicsCharacter.h"
 #include "PhysicsController.h"
 #include "PhysicsRigidBody.h"
-#include "ScriptListener.h"
 #include "lua_PhysicsControllerListenerEventType.h"
 
 namespace gameplay

+ 0 - 1
gameplay/src/lua/lua_PhysicsControllerListener.cpp

@@ -8,7 +8,6 @@
 #include "PhysicsCharacter.h"
 #include "PhysicsController.h"
 #include "PhysicsRigidBody.h"
-#include "ScriptListener.h"
 #include "lua_PhysicsControllerListenerEventType.h"
 
 namespace gameplay

+ 1 - 1
gameplay/src/lua/lua_PhysicsGhostObject.cpp

@@ -9,7 +9,7 @@
 #include "PhysicsCollisionObject.h"
 #include "PhysicsController.h"
 #include "PhysicsGhostObject.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"

+ 1 - 1
gameplay/src/lua/lua_PhysicsRigidBody.cpp

@@ -11,7 +11,7 @@
 #include "PhysicsCollisionObject.h"
 #include "PhysicsController.h"
 #include "PhysicsRigidBody.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"

+ 1 - 1
gameplay/src/lua/lua_PhysicsRigidBodyParameters.cpp

@@ -11,7 +11,7 @@
 #include "PhysicsCollisionObject.h"
 #include "PhysicsController.h"
 #include "PhysicsRigidBody.h"
-#include "ScriptListener.h"
+#include "ScriptController.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_PhysicsCollisionObjectCollisionListenerEventType.h"

+ 0 - 16
gameplay/src/lua/lua_RadioButton.cpp

@@ -11,7 +11,6 @@
 #include "Node.h"
 #include "RadioButton.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
@@ -197,21 +196,6 @@ int lua_RadioButton_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                RadioButton* instance = getInstance(state);
-                instance->Button::Control::addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_RadioButton_addListener - Failed to match the given parameters to a valid function signature.");

+ 66 - 0
gameplay/src/lua/lua_ScriptController.cpp

@@ -13,6 +13,7 @@ void luaRegister_ScriptController()
     const luaL_Reg lua_members[] = 
     {
         {"loadScript", lua_ScriptController_loadScript},
+        {"loadUrl", lua_ScriptController_loadUrl},
         {NULL, NULL}
     };
     const luaL_Reg* lua_statics = NULL;
@@ -56,6 +57,71 @@ int lua_ScriptController_loadScript(lua_State* state)
             }
             break;
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = ScriptUtil::getString(2, false);
+
+                // Get parameter 2 off the stack.
+                bool param2 = ScriptUtil::luaCheckBool(state, 3);
+
+                ScriptController* instance = getInstance(state);
+                instance->loadScript(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_ScriptController_loadScript - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_ScriptController_loadUrl(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = ScriptUtil::getString(2, false);
+
+                ScriptController* instance = getInstance(state);
+                std::string result = instance->loadUrl(param1);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result.c_str());
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_ScriptController_loadUrl - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
         default:
         {
             lua_pushstring(state, "Invalid number of parameters (expected 2).");

+ 1 - 0
gameplay/src/lua/lua_ScriptController.h

@@ -6,6 +6,7 @@ namespace gameplay
 
 // Lua bindings for ScriptController.
 int lua_ScriptController_loadScript(lua_State* state);
+int lua_ScriptController_loadUrl(lua_State* state);
 
 void luaRegister_ScriptController();
 

+ 0 - 16
gameplay/src/lua/lua_Slider.cpp

@@ -9,7 +9,6 @@
 #include "Label.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "Slider.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
@@ -201,21 +200,6 @@ int lua_Slider_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                Slider* instance = getInstance(state);
-                instance->Label::Control::addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Slider_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 16
gameplay/src/lua/lua_TextBox.cpp

@@ -9,7 +9,6 @@
 #include "Label.h"
 #include "Node.h"
 #include "Ref.h"
-#include "ScriptListener.h"
 #include "TextBox.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlListenerEventType.h"
@@ -194,21 +193,6 @@ int lua_TextBox_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                int param2 = (int)luaL_checkint(state, 3);
-
-                TextBox* instance = getInstance(state);
-                instance->Label::Control::addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_TextBox_addListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 38
gameplay/src/lua/lua_Transform.cpp

@@ -6,7 +6,6 @@
 #include "Base.h"
 #include "Game.h"
 #include "Node.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 
@@ -299,17 +298,6 @@ int lua_Transform_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                Transform* instance = getInstance(state);
-                instance->addListener(param1);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Transform_addListener - Failed to match the given parameters to a valid function signature.");
@@ -334,21 +322,6 @@ int lua_Transform_addListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                // Get parameter 2 off the stack.
-                long param2 = (long)luaL_checklong(state, 3);
-
-                Transform* instance = getInstance(state);
-                instance->addListener(param1, param2);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Transform_addListener - Failed to match the given parameters to a valid function signature.");
@@ -1822,17 +1795,6 @@ int lua_Transform_removeListener(lua_State* state)
                 
                 return 0;
             }
-            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(2, false);
-
-                Transform* instance = getInstance(state);
-                instance->removeListener(param1);
-                
-                return 0;
-            }
             else
             {
                 lua_pushstring(state, "lua_Transform_removeListener - Failed to match the given parameters to a valid function signature.");

+ 0 - 1
gameplay/src/lua/lua_TransformListener.cpp

@@ -6,7 +6,6 @@
 #include "Base.h"
 #include "Game.h"
 #include "Node.h"
-#include "ScriptListener.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"