Browse Source

Merge pull request #910 from sgrenier/next

Added public methods to register global script callbacks
Steve Grenier 12 years ago
parent
commit
51ef561cb3

+ 11 - 19
gameplay/src/Game.cpp

@@ -123,30 +123,22 @@ bool Game::startup()
         Properties* scripts = _properties->getNamespace("scripts", true);
         if (scripts)
         {
-            const char* name;
-            while ((name = scripts->getNextProperty()) != NULL)
+            const char* callback;
+            while ((callback = scripts->getNextProperty()) != NULL)
             {
-                ScriptController::ScriptCallback callback = ScriptController::toCallback(name);
-                if (callback != ScriptController::INVALID_CALLBACK)
+                std::string url = scripts->getString();
+                std::string file;
+                std::string id;
+                splitURL(url, &file, &id);
+
+                if (file.size() <= 0 || id.size() <= 0)
                 {
-                    std::string url = scripts->getString();
-                    std::string file;
-                    std::string id;
-                    splitURL(url, &file, &id);
-
-                    if (file.size() <= 0 || id.size() <= 0)
-                    {
-                        GP_ERROR("Invalid %s script callback function '%s'.", name, url.c_str());
-                    }
-                    else
-                    {
-                        _scriptController->loadScript(file.c_str());
-                        _scriptController->registerCallback(callback, id);
-                    }
+                    GP_ERROR("Invalid %s script callback function '%s'.", callback, url.c_str());
                 }
                 else
                 {
-                    // Ignore everything else.
+                    _scriptController->loadScript(file.c_str());
+                    _scriptController->registerCallback(callback, id.c_str());
                 }
             }
         }

+ 56 - 49
gameplay/src/ScriptController.cpp

@@ -641,15 +641,10 @@ void ScriptController::print(const char* str1, const char* str2)
 
 ScriptController::ScriptController() : _lua(NULL)
 {
-    memset(_callbacks, 0, sizeof(std::string*) * CALLBACK_COUNT);
 }
 
 ScriptController::~ScriptController()
 {
-    for (unsigned int i = 0; i < CALLBACK_COUNT; i++)
-    {
-        SAFE_DELETE(_callbacks[i]);
-    }
 }
 
 static const char* lua_print_function = 
@@ -710,10 +705,9 @@ void ScriptController::initialize()
 
 void ScriptController::initializeGame()
 {
-    if (_callbacks[INITIALIZE])
-    {
-        executeFunction<void>(_callbacks[INITIALIZE]->c_str());
-    }
+    std::vector<std::string>& list = _callbacks[INITIALIZE];
+    for (size_t i = 0, count = list.size(); i < count; ++i)
+        executeFunction<void>(list[i].c_str());
 }
 
 void ScriptController::finalize()
@@ -727,21 +721,15 @@ void ScriptController::finalize()
 
 void ScriptController::finalizeGame()
 {
-	std::string finalizeCallback;
-	if (_callbacks[FINALIZE])
-		finalizeCallback = _callbacks[FINALIZE]->c_str();
+    std::vector<std::string> finalizeCallbacks = _callbacks[FINALIZE]; // no & : makes a copy of the vector
 
 	// Remove any registered callbacks so they don't get called after shutdown
 	for (unsigned int i = 0; i < CALLBACK_COUNT; i++)
-    {
-        SAFE_DELETE(_callbacks[i]);
-    }
+        _callbacks[i].clear();
 
-	// Fire script finalize callback
-    if (!finalizeCallback.empty())
-	{
-        executeFunction<void>(finalizeCallback.c_str());
-    }
+	// Fire script finalize callbacks
+    for (size_t i = 0, count = finalizeCallbacks.size(); i < count; ++i)
+        executeFunction<void>(finalizeCallbacks[i].c_str());
 
     // Perform a full garbage collection cycle.
 	// Note that this does NOT free any global variables declared in scripts, since 
@@ -752,59 +740,55 @@ void ScriptController::finalizeGame()
 
 void ScriptController::update(float elapsedTime)
 {
-    if (_callbacks[UPDATE])
-    {
-        executeFunction<void>(_callbacks[UPDATE]->c_str(), "f", elapsedTime);
-    }
+    std::vector<std::string>& list = _callbacks[UPDATE];
+    for (size_t i = 0, count = list.size(); i < count; ++i)
+        executeFunction<void>(list[i].c_str(), "f", elapsedTime);
 }
 
 void ScriptController::render(float elapsedTime)
 {
-    if (_callbacks[RENDER])
-    {
-        executeFunction<void>(_callbacks[RENDER]->c_str(), "f", elapsedTime);
-    }
+    std::vector<std::string>& list = _callbacks[RENDER];
+    for (size_t i = 0, count = list.size(); i < count; ++i)
+        executeFunction<void>(list[i].c_str(), "f", elapsedTime);
 }
 
 void ScriptController::resizeEvent(unsigned int width, unsigned int height)
 {
-    if (_callbacks[RESIZE_EVENT])
-    {
-        executeFunction<void>(_callbacks[RESIZE_EVENT]->c_str(), "uiui", width, height);
-    }
+    std::vector<std::string>& list = _callbacks[RESIZE_EVENT];
+    for (size_t i = 0, count = list.size(); i < count; ++i)
+        executeFunction<void>(list[i].c_str(), "uiui", width, height);
 }
 
 void ScriptController::keyEvent(Keyboard::KeyEvent evt, int key)
 {
-    if (_callbacks[KEY_EVENT])
-    {
-        executeFunction<void>(_callbacks[KEY_EVENT]->c_str(), "[Keyboard::KeyEvent][Keyboard::Key]", evt, key);
-    }
+    std::vector<std::string>& list = _callbacks[KEY_EVENT];
+    for (size_t i = 0, count = list.size(); i < count; ++i)
+        executeFunction<void>(list[i].c_str(), "[Keyboard::KeyEvent][Keyboard::Key]", evt, key);
 }
 
 void ScriptController::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
 {
-    if (_callbacks[TOUCH_EVENT])
-    {
-        executeFunction<void>(_callbacks[TOUCH_EVENT]->c_str(), "[Touch::TouchEvent]iiui", evt, x, y, contactIndex);
-    }
+    std::vector<std::string>& list = _callbacks[TOUCH_EVENT];
+    for (size_t i = 0, count = list.size(); i < count; ++i)
+        executeFunction<void>(list[i].c_str(), "[Touch::TouchEvent]iiui", evt, x, y, contactIndex);
 }
 
 bool ScriptController::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
 {
-    if (_callbacks[MOUSE_EVENT])
+    std::vector<std::string>& list = _callbacks[MOUSE_EVENT];
+    for (size_t i = 0, count = list.size(); i < count; ++i)
     {
-        return executeFunction<bool>(_callbacks[MOUSE_EVENT]->c_str(), "[Mouse::MouseEvent]iii", evt, x, y, wheelDelta);
+        if (executeFunction<bool>(list[i].c_str(), "[Mouse::MouseEvent]iii", evt, x, y, wheelDelta))
+            return true;
     }
     return false;
 }
 
 void ScriptController::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
 {
-    if (_callbacks[GAMEPAD_EVENT])
-    {
-        executeFunction<void>(_callbacks[GAMEPAD_EVENT]->c_str(), "[Gamepad::GamepadEvent]<Gamepad>", evt, gamepad);
-    }
+    std::vector<std::string>& list = _callbacks[GAMEPAD_EVENT];
+    for (size_t i = 0, count = list.size(); i < count; ++i)
+        executeFunction<void>(list[i].c_str(), "[Gamepad::GamepadEvent]<Gamepad>", evt, gamepad);
 }
 
 void ScriptController::executeFunctionHelper(int resultCount, const char* func, const char* args, va_list* list)
@@ -935,10 +919,33 @@ void ScriptController::executeFunctionHelper(int resultCount, const char* func,
         GP_WARN("Failed to call function '%s' with error '%s'.", func, lua_tostring(_lua, -1));
 }
 
-void ScriptController::registerCallback(ScriptCallback callback, const std::string& function)
+void ScriptController::registerCallback(const char* callback, const char* function)
 {
-    SAFE_DELETE(_callbacks[callback]);
-    _callbacks[callback] = new std::string(function);
+    ScriptCallback scb = toCallback(callback);
+    if (scb < INVALID_CALLBACK)
+    {
+        _callbacks[scb].push_back(function);
+    }
+    else
+    {
+        GP_WARN("Invalid script callback function specified: %s", callback);
+    }
+}
+
+void ScriptController::unregisterCallback(const char* callback, const char* function)
+{
+    ScriptCallback scb = toCallback(callback);
+    if (scb < INVALID_CALLBACK)
+    {
+        std::vector<std::string>& list = _callbacks[scb];
+        std::vector<std::string>::iterator itr = std::find(list.begin(), list.end(), std::string(function));
+        if (itr != list.end())
+            list.erase(itr);
+    }
+    else
+    {
+        GP_WARN("Invalid script callback function specified: %s", callback);
+    }
 }
 
 ScriptController::ScriptCallback ScriptController::toCallback(const char* name)

+ 27 - 10
gameplay/src/ScriptController.h

@@ -349,6 +349,7 @@ class ScriptController
     friend class Platform;
 
 public:
+
     /**
      * Loads the given script file and executes its global code.
      * 
@@ -366,6 +367,30 @@ public:
      */
     std::string loadUrl(const char* url);
 
+    /**
+     * Registers the given script callback.
+     *
+     * The 'callback' parameter must be one of the supported global callback
+     * event functions. The following strings are accepted: initialize, finalize,
+     * update, render, resizeEvent, keyEvent, touchEvent, mouseEvent, gamepadEvent.
+     * Signatures for the registered script function must match that of the
+     * corresponding signatures of these events on the Game class.
+     *
+     * @param callback The script callback to register for.
+     * @param function The name of the script function to register.
+     */
+    void registerCallback(const char* callback, const char* function);
+
+    /**
+     * Unregisters the given script callback.
+     *
+     * @param callback The script callback to unregister for.
+     * @param function The name of the script function to unregister.
+     *
+     * @see registerCallback(const char*, const char*)
+     */
+    void unregisterCallback(const char* callback, const char* function);
+
     /**
      * Calls the specified no-parameter Lua function.
      * 
@@ -732,7 +757,7 @@ public:
 private:
 
     /**
-     * Represents a Lua callback function binding.
+     * Represents a callback function that can be registered for.
      */
     enum ScriptCallback
     {
@@ -875,14 +900,6 @@ private:
      */
     void executeFunctionHelper(int resultCount, const char* func, const char* args, va_list* list);
 
-    /**
-     * Registers the given script callback.
-     * 
-     * @param callback The script callback to register for.
-     * @param function The name of the function within the Lua script to call.
-     */
-    void registerCallback(ScriptCallback callback, const std::string& function);
-
     /**
      * Converts the given string to a valid script callback enumeration value
      * or to ScriptController::INVALID_CALLBACK if there is no valid conversion.
@@ -945,7 +962,7 @@ private:
     lua_State* _lua;
     unsigned int _returnCount;
     std::map<std::string, std::vector<std::string> > _hierarchy;
-    std::string* _callbacks[CALLBACK_COUNT];
+    std::vector<std::string> _callbacks[CALLBACK_COUNT];
     std::set<std::string> _loadedScripts;
     std::vector<luaStringEnumConversionFunction> _stringFromEnum;
 };

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

@@ -41,10 +41,12 @@ void luaRegister_Camera()
         {"pickRay", lua_Camera_pickRay},
         {"project", lua_Camera_project},
         {"release", lua_Camera_release},
+        {"resetProjectionMatrix", lua_Camera_resetProjectionMatrix},
         {"setAspectRatio", lua_Camera_setAspectRatio},
         {"setFarPlane", lua_Camera_setFarPlane},
         {"setFieldOfView", lua_Camera_setFieldOfView},
         {"setNearPlane", lua_Camera_setNearPlane},
+        {"setProjectionMatrix", lua_Camera_setProjectionMatrix},
         {"setZoomX", lua_Camera_setZoomX},
         {"setZoomY", lua_Camera_setZoomY},
         {"unproject", lua_Camera_unproject},
@@ -925,6 +927,38 @@ int lua_Camera_release(lua_State* state)
     return 0;
 }
 
+int lua_Camera_resetProjectionMatrix(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 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Camera* instance = getInstance(state);
+                instance->resetProjectionMatrix();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Camera_resetProjectionMatrix - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Camera_setAspectRatio(lua_State* state)
 {
     // Get the number of parameters.
@@ -1069,6 +1103,48 @@ int lua_Camera_setNearPlane(lua_State* state)
     return 0;
 }
 
+int lua_Camera_setProjectionMatrix(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_TUSERDATA || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                gameplay::ScriptUtil::LuaArray<Matrix> param1 = gameplay::ScriptUtil::getObjectPointer<Matrix>(2, "Matrix", true, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Matrix'.");
+                    lua_error(state);
+                }
+
+                Camera* instance = getInstance(state);
+                instance->setProjectionMatrix(*param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Camera_setProjectionMatrix - 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).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Camera_setZoomX(lua_State* state)
 {
     // Get the number of parameters.

+ 2 - 0
gameplay/src/lua/lua_Camera.h

@@ -25,10 +25,12 @@ int lua_Camera_getZoomY(lua_State* state);
 int lua_Camera_pickRay(lua_State* state);
 int lua_Camera_project(lua_State* state);
 int lua_Camera_release(lua_State* state);
+int lua_Camera_resetProjectionMatrix(lua_State* state);
 int lua_Camera_setAspectRatio(lua_State* state);
 int lua_Camera_setFarPlane(lua_State* state);
 int lua_Camera_setFieldOfView(lua_State* state);
 int lua_Camera_setNearPlane(lua_State* state);
+int lua_Camera_setProjectionMatrix(lua_State* state);
 int lua_Camera_setZoomX(lua_State* state);
 int lua_Camera_setZoomY(lua_State* state);
 int lua_Camera_static_create(lua_State* state);

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

@@ -32,6 +32,7 @@ void luaRegister_FrameBuffer()
     {
         {"bindDefault", lua_FrameBuffer_static_bindDefault},
         {"create", lua_FrameBuffer_static_create},
+        {"getCurrent", lua_FrameBuffer_static_getCurrent},
         {"getFrameBuffer", lua_FrameBuffer_static_getFrameBuffer},
         {"getMaxRenderTargets", lua_FrameBuffer_static_getMaxRenderTargets},
         {NULL, NULL}
@@ -759,6 +760,43 @@ int lua_FrameBuffer_static_create(lua_State* state)
     return 0;
 }
 
+int lua_FrameBuffer_static_getCurrent(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 0:
+        {
+            void* returnPtr = (void*)FrameBuffer::getCurrent();
+            if (returnPtr)
+            {
+                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                object->instance = returnPtr;
+                object->owns = false;
+                luaL_getmetatable(state, "FrameBuffer");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_FrameBuffer_static_getFrameBuffer(lua_State* state)
 {
     // Get the number of parameters.

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

@@ -21,6 +21,7 @@ int lua_FrameBuffer_setDepthStencilTarget(lua_State* state);
 int lua_FrameBuffer_setRenderTarget(lua_State* state);
 int lua_FrameBuffer_static_bindDefault(lua_State* state);
 int lua_FrameBuffer_static_create(lua_State* state);
+int lua_FrameBuffer_static_getCurrent(lua_State* state);
 int lua_FrameBuffer_static_getFrameBuffer(lua_State* state);
 int lua_FrameBuffer_static_getMaxRenderTargets(lua_State* state);
 

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

@@ -14,6 +14,8 @@ void luaRegister_ScriptController()
     {
         {"loadScript", lua_ScriptController_loadScript},
         {"loadUrl", lua_ScriptController_loadUrl},
+        {"registerCallback", lua_ScriptController_registerCallback},
+        {"unregisterCallback", lua_ScriptController_unregisterCallback},
         {NULL, NULL}
     };
     const luaL_Reg lua_statics[] = 
@@ -130,6 +132,46 @@ int lua_ScriptController_loadUrl(lua_State* state)
     return 0;
 }
 
+int lua_ScriptController_registerCallback(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 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_TSTRING || lua_type(state, 3) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                // Get parameter 2 off the stack.
+                const char* param2 = gameplay::ScriptUtil::getString(3, false);
+
+                ScriptController* instance = getInstance(state);
+                instance->registerCallback(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_ScriptController_registerCallback - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_ScriptController_static_print(lua_State* state)
 {
     // Get the number of parameters.
@@ -190,4 +232,44 @@ int lua_ScriptController_static_print(lua_State* state)
     return 0;
 }
 
+int lua_ScriptController_unregisterCallback(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 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_TSTRING || lua_type(state, 3) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                // Get parameter 2 off the stack.
+                const char* param2 = gameplay::ScriptUtil::getString(3, false);
+
+                ScriptController* instance = getInstance(state);
+                instance->unregisterCallback(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_ScriptController_unregisterCallback - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 }

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

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