From 8eebb889e37c37d7bf5ebd689c056f91e98856f9 Mon Sep 17 00:00:00 2001 From: mathiaswking Date: Fri, 15 Nov 2019 19:04:23 +0100 Subject: [PATCH] Use Lua callback handling functions from DefoldSDK --- extension-iap/src/iap_android.cpp | 111 +++++++----------------------- extension-iap/src/iap_ios.mm | 52 +++++++------- extension-iap/src/iap_private.cpp | 59 ---------------- extension-iap/src/iap_private.h | 18 +---- 4 files changed, 52 insertions(+), 188 deletions(-) diff --git a/extension-iap/src/iap_android.cpp b/extension-iap/src/iap_android.cpp index 6dbfe06..7b2f879 100644 --- a/extension-iap/src/iap_android.cpp +++ b/extension-iap/src/iap_android.cpp @@ -27,20 +27,15 @@ struct IAP IAP() { memset(this, 0, sizeof(*this)); - m_Callback = LUA_NOREF; - m_Self = LUA_NOREF; - m_Listener.m_Callback = LUA_NOREF; - m_Listener.m_Self = LUA_NOREF; m_autoFinishTransactions = true; m_ProviderId = PROVIDER_ID_GOOGLE; } int m_InitCount; - int m_Callback; - int m_Self; bool m_autoFinishTransactions; int m_ProviderId; - lua_State* m_L; - IAPListener m_Listener; + + dmScript::LuaCallbackInfo* m_ProductCallback; + dmScript::LuaCallbackInfo* m_Listener; jobject m_IAP; jobject m_IAPJNI; @@ -56,22 +51,9 @@ struct IAP static IAP g_IAP; -static void ResetCallback(lua_State* L) -{ - if (g_IAP.m_Callback != LUA_NOREF) { - dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Callback); - dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Self); - g_IAP.m_Callback = LUA_NOREF; - g_IAP.m_Self = LUA_NOREF; - g_IAP.m_L = 0; - } -} - static int IAP_List(lua_State* L) { int top = lua_gettop(L); - ResetCallback(L); - char* buf = IAP_List_CreateBuffer(L); if( buf == 0 ) { @@ -79,14 +61,10 @@ static int IAP_List(lua_State* L) return 0; } - luaL_checktype(L, 2, LUA_TFUNCTION); - lua_pushvalue(L, 2); - g_IAP.m_Callback = dmScript::Ref(L, LUA_REGISTRYINDEX); + if (g_IAP.m_ProductCallback) + dmScript::DestroyCallback(g_IAP.m_ProductCallback); - dmScript::GetInstance(L); - g_IAP.m_Self = dmScript::Ref(L, LUA_REGISTRYINDEX); - - g_IAP.m_L = dmScript::GetMainThread(L); + g_IAP.m_ProductCallback = dmScript::CreateCallback(L, 2); JNIEnv* env = Attach(); jstring products = env->NewStringUTF(buf); @@ -180,22 +158,13 @@ static int IAP_Restore(lua_State* L) static int IAP_SetListener(lua_State* L) { IAP* iap = &g_IAP; - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_pushvalue(L, 1); - int cb = dmScript::Ref(L, LUA_REGISTRYINDEX); - bool had_previous = false; - if (iap->m_Listener.m_Callback != LUA_NOREF) { - dmScript::Unref(iap->m_Listener.m_L, LUA_REGISTRYINDEX, iap->m_Listener.m_Callback); - dmScript::Unref(iap->m_Listener.m_L, LUA_REGISTRYINDEX, iap->m_Listener.m_Self); - had_previous = true; - } + bool had_previous = iap->m_Listener != 0; - iap->m_Listener.m_L = dmScript::GetMainThread(L); - iap->m_Listener.m_Callback = cb; + if (iap->m_Listener) + dmScript::DestroyCallback(iap->m_Listener); - dmScript::GetInstance(L); - iap->m_Listener.m_Self = dmScript::Ref(L, LUA_REGISTRYINDEX); + iap->m_Listener = dmScript::CreateCallback(L, 1); // On first set listener, trigger process old ones. if (!had_previous) { @@ -238,6 +207,7 @@ JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onProductsResult__ILjava_lang_ } IAPCommand cmd; + cmd.m_Callback = g_IAP.m_ProductCallback; cmd.m_Command = IAP_PRODUCT_RESULT; cmd.m_ResponseCode = responseCode; if (pl) @@ -257,6 +227,7 @@ JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onPurchaseResult__ILjava_lang_ } IAPCommand cmd; + cmd.m_Callback = g_IAP.m_Listener; cmd.m_Command = IAP_PURCHASE_RESULT; cmd.m_ResponseCode = responseCode; if (pd) @@ -273,25 +244,11 @@ JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onPurchaseResult__ILjava_lang_ static void HandleProductResult(const IAPCommand* cmd) { - lua_State* L = g_IAP.m_L; + lua_State* L = dmScript::GetCallbackLuaContext(cmd->m_Callback); int top = lua_gettop(L); - if (g_IAP.m_Callback == LUA_NOREF) { - dmLogError("No callback set"); - return; - } - - lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAP.m_Callback); - - // Setup self - lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAP.m_Self); - lua_pushvalue(L, -1); - dmScript::SetInstance(L); - - if (!dmScript::IsInstanceValid(L)) + if (!dmScript::SetupCallback(cmd->m_Callback)) { - dmLogError("Could not run IAP callback because the instance has been deleted."); - lua_pop(L, 2); assert(top == lua_gettop(L)); return; } @@ -326,36 +283,21 @@ static void HandleProductResult(const IAPCommand* cmd) lua_pop(L, 1); } - dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Callback); - dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Self); - g_IAP.m_Callback = LUA_NOREF; - g_IAP.m_Self = LUA_NOREF; + dmScript::TeardownCallback(cmd->m_Callback); + dmScript::DestroyCallback(cmd->m_Callback); + assert(g_IAP.m_ProductCallback == cmd->m_Callback); + g_IAP.m_ProductCallback = 0; assert(top == lua_gettop(L)); } static void HandlePurchaseResult(const IAPCommand* cmd) { - lua_State* L = g_IAP.m_Listener.m_L; + lua_State* L = dmScript::GetCallbackLuaContext(cmd->m_Callback); int top = lua_gettop(L); - if (g_IAP.m_Listener.m_Callback == LUA_NOREF) { - dmLogError("No callback set"); - return; - } - - - lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAP.m_Listener.m_Callback); - - // Setup self - lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAP.m_Listener.m_Self); - lua_pushvalue(L, -1); - dmScript::SetInstance(L); - - if (!dmScript::IsInstanceValid(L)) + if (!dmScript::SetupCallback(cmd->m_Callback)) { - dmLogError("Could not run IAP callback because the instance has been deleted."); - lua_pop(L, 2); assert(top == lua_gettop(L)); return; } @@ -393,12 +335,14 @@ static void HandlePurchaseResult(const IAPCommand* cmd) IAP_PushError(L, "failed to buy product", REASON_UNSPECIFIED); } - int ret = lua_pcall(L, 3, 0, 0); + int ret = dmScript::PCall(L, 3, 0); if (ret != 0) { dmLogError("Error running callback: %s", lua_tostring(L, -1)); lua_pop(L, 1); } + dmScript::TeardownCallback(cmd->m_Callback); + assert(top == lua_gettop(L)); } @@ -500,12 +444,9 @@ static dmExtension::Result FinalizeIAP(dmExtension::Params* params) IAP_Queue_Destroy(&g_IAP.m_CommandQueue); --g_IAP.m_InitCount; - if (params->m_L == g_IAP.m_Listener.m_L && g_IAP.m_Listener.m_Callback != LUA_NOREF) { - dmScript::Unref(g_IAP.m_Listener.m_L, LUA_REGISTRYINDEX, g_IAP.m_Listener.m_Callback); - dmScript::Unref(g_IAP.m_Listener.m_L, LUA_REGISTRYINDEX, g_IAP.m_Listener.m_Self); - g_IAP.m_Listener.m_L = 0; - g_IAP.m_Listener.m_Callback = LUA_NOREF; - g_IAP.m_Listener.m_Self = LUA_NOREF; + if (params->m_L == dmScript::GetCallbackLuaContext(g_IAP.m_Listener)) { + dmScript::DestroyCallback(g_IAP.m_Listener); + g_IAP.m_Listener = 0; } if (g_IAP.m_InitCount == 0) { diff --git a/extension-iap/src/iap_ios.mm b/extension-iap/src/iap_ios.mm index 89d9fa8..20c4683 100644 --- a/extension-iap/src/iap_ios.mm +++ b/extension-iap/src/iap_ios.mm @@ -23,12 +23,11 @@ struct IAP { memset(this, 0, sizeof(*this)); m_AutoFinishTransactions = true; - IAP_ClearCallback(&m_Listener); } int m_InitCount; bool m_AutoFinishTransactions; NSMutableDictionary* m_PendingTransactions; - IAPListener m_Listener; + dmScript::LuaCallbackInfo* m_Listener; IAPCommandQueue m_CommandQueue; SKPaymentTransactionObserver* m_Observer; }; @@ -101,15 +100,14 @@ static void IAP_FreeTransaction(IAPTransaction* transaction) @interface SKProductsRequestDelegate : NSObject - @property IAPListener m_Callback; + @property dmScript::LuaCallbackInfo* m_Callback; @property (assign) SKProductsRequest* m_Request; @end @implementation SKProductsRequestDelegate - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ - IAPListener callback = self.m_Callback; - if (!IAP_CallbackIsValid(&callback)) { + if (!dmScript::IsCallbackValid(self.m_Callback)) { dmLogError("No callback set"); return; } @@ -141,7 +139,7 @@ static void IAP_FreeTransaction(IAPTransaction* transaction) IAPCommand cmd; cmd.m_Command = IAP_PRODUCT_RESULT; - cmd.m_Callback = callback; + cmd.m_Callback = self.m_Callback; cmd.m_Data = iap_response; IAP_Queue_Push(&g_IAP.m_CommandQueue, &cmd); } @@ -151,10 +149,10 @@ static void HandleProductResult(IAPCommand* cmd) IAPResponse* response = (IAPResponse*)cmd->m_Data; - lua_State* L = cmd->m_Callback.m_L; + lua_State* L = dmScript::GetCallbackLuaContext(g_IAP.m_Listener); int top = lua_gettop(L); - if (!IAP_SetupCallback(&cmd->m_Callback)) + if (!dmScript::SetupCallback(cmd->m_Callback)) { assert(top == lua_gettop(L)); delete response; @@ -188,13 +186,14 @@ static void HandleProductResult(IAPCommand* cmd) } lua_pushnil(L); - int ret = lua_pcall(L, 3, 0, 0); + int ret = dmScript::PCall(L, 3, 0); if (ret != 0) { dmLogError("%d: Error running callback: %s", __LINE__, lua_tostring(L, -1)); lua_pop(L, 1); } - IAP_UnregisterCallback(&cmd->m_Callback); + dmScript::TeardownCallback(cmd->m_Callback); + dmScript::DestroyCallback(cmd->m_Callback); delete response; assert(top == lua_gettop(L)); @@ -203,8 +202,7 @@ static void HandleProductResult(IAPCommand* cmd) - (void)request:(SKRequest *)request didFailWithError:(NSError *)error{ dmLogWarning("SKProductsRequest failed: %s", [error.localizedDescription UTF8String]); - IAPListener callback = self.m_Callback; - if (!IAP_CallbackIsValid(&callback)) { + if (!dmScript::IsCallbackValid(self.m_Callback)) { dmLogError("No callback set"); return; } @@ -215,7 +213,7 @@ static void HandleProductResult(IAPCommand* cmd) IAPCommand cmd; cmd.m_Command = IAP_PRODUCT_RESULT; - cmd.m_Callback = callback; + cmd.m_Callback = self.m_Callback; cmd.m_Data = response; IAP_Queue_Push(&g_IAP.m_CommandQueue, &cmd); @@ -300,13 +298,12 @@ static void PushTransaction(lua_State* L, IAPTransaction* transaction) static void HandlePurchaseResult(IAPCommand* cmd) { - IAPTransaction* transaction = (IAPTransaction*)cmd->m_Data; - lua_State* L = cmd->m_Callback.m_L; + lua_State* L = dmScript::GetCallbackLuaContext(cmd->m_Callback); int top = lua_gettop(L); - if (!IAP_SetupCallback(&cmd->m_Callback)) + if (!dmScript::SetupCallback(cmd->m_Callback)) { assert(top == lua_gettop(L)); return; @@ -321,12 +318,14 @@ static void HandlePurchaseResult(IAPCommand* cmd) lua_pushnil(L); } - int ret = lua_pcall(L, 3, 0, 0); + int ret = dmScript::PCall(L, 3, 0); if (ret != 0) { dmLogError("%d: Error running callback: %s", __LINE__, lua_tostring(L, -1)); lua_pop(L, 1); } + dmScript::TeardownCallback(cmd->m_Callback); + IAP_FreeTransaction(transaction); delete transaction; @@ -344,8 +343,7 @@ static void HandlePurchaseResult(IAPCommand* cmd) [self.m_IAP->m_PendingTransactions setObject:transaction forKey:[NSNumber numberWithInteger:trans_id_hash] ]; } - bool has_listener = self.m_IAP->m_Listener.m_Callback != LUA_NOREF; - if (!has_listener) + if (!self.m_IAP->m_Listener) continue; IAPTransaction* iap_transaction = new IAPTransaction; @@ -394,10 +392,7 @@ static int IAP_List(lua_State* L) SKProductsRequest* products_request = [[SKProductsRequest alloc] initWithProductIdentifiers: product_identifiers]; SKProductsRequestDelegate* delegate = [SKProductsRequestDelegate alloc]; - IAPListener callback; - IAP_RegisterCallback(L, 2, &callback); - delegate.m_Callback = callback; - + delegate.m_Callback = dmScript::CreateCallback(L, 2); delegate.m_Request = products_request; products_request.delegate = delegate; [products_request start]; @@ -486,8 +481,10 @@ static int IAP_SetListener(lua_State* L) { IAP* iap = &g_IAP; - IAP_UnregisterCallback(&iap->m_Listener); - IAP_RegisterCallback(L, 1, &iap->m_Listener); + if (iap->m_Listener) + dmScript::DestroyCallback(iap->m_Listener); + + iap->m_Listener = dmScript::CreateCallback(L, 1); if (g_IAP.m_Observer == 0) { SKPaymentTransactionObserver* observer = [[SKPaymentTransactionObserver alloc] init]; @@ -577,8 +574,9 @@ static dmExtension::Result FinalizeIAP(dmExtension::Params* params) // TODO: Should we support one listener per lua-state? // Or just use a single lua-state...? - if (params->m_L == g_IAP.m_Listener.m_L) { - IAP_UnregisterCallback(&g_IAP.m_Listener); + if (params->m_L == dmScript::GetCallbackLuaContext(g_IAP.m_Listener)) { + dmScript::DestroyCallback(g_IAP.m_Listener); + g_IAP.m_Listener = 0; } if (g_IAP.m_InitCount == 0) { diff --git a/extension-iap/src/iap_private.cpp b/extension-iap/src/iap_private.cpp index a295f48..b6ad5b9 100644 --- a/extension-iap/src/iap_private.cpp +++ b/extension-iap/src/iap_private.cpp @@ -7,65 +7,6 @@ #include #include - -IAPListener::IAPListener() { - IAP_ClearCallback(this); -} - -void IAP_ClearCallback(IAPListener* callback) -{ - callback->m_L = 0; - callback->m_Callback = LUA_NOREF; - callback->m_Self = LUA_NOREF; -} - -void IAP_RegisterCallback(lua_State* L, int index, IAPListener* callback) -{ - luaL_checktype(L, index, LUA_TFUNCTION); - lua_pushvalue(L, index); - callback->m_Callback = dmScript::Ref(L, LUA_REGISTRYINDEX); - - dmScript::GetInstance(L); - callback->m_Self = dmScript::Ref(L, LUA_REGISTRYINDEX); - - callback->m_L = L; -} - -void IAP_UnregisterCallback(IAPListener* callback) -{ - if (LUA_NOREF != callback->m_Callback) - dmScript::Unref(callback->m_L, LUA_REGISTRYINDEX, callback->m_Callback); - if (LUA_NOREF != callback->m_Self) - dmScript::Unref(callback->m_L, LUA_REGISTRYINDEX, callback->m_Self); - callback->m_Callback = LUA_NOREF; - callback->m_Self = LUA_NOREF; - callback->m_L = 0; -} - -bool IAP_SetupCallback(IAPListener* callback) -{ - lua_State* L = callback->m_L; - lua_rawgeti(L, LUA_REGISTRYINDEX, callback->m_Callback); - - // Setup self - lua_rawgeti(L, LUA_REGISTRYINDEX, callback->m_Self); - lua_pushvalue(L, -1); - dmScript::SetInstance(L); - - if (!dmScript::IsInstanceValid(L)) - { - dmLogError("Could not run callback because the instance has been deleted."); - lua_pop(L, 2); - return false; - } - return true; -} - -bool IAP_CallbackIsValid(IAPListener* callback) -{ - return callback != 0 && callback->m_L != 0 && callback->m_Callback != LUA_NOREF && callback->m_Self != LUA_NOREF; -} - // Creates a comma separated string, given a table where all values are strings (or numbers) // Returns a malloc'ed string, which the caller must free char* IAP_List_CreateBuffer(lua_State* L) diff --git a/extension-iap/src/iap_private.h b/extension-iap/src/iap_private.h index 44c0852..c03556c 100644 --- a/extension-iap/src/iap_private.h +++ b/extension-iap/src/iap_private.h @@ -5,16 +5,6 @@ #include -// TODO: Rename Callback -struct IAPListener -{ - IAPListener(); - - lua_State* m_L; - int m_Callback; - int m_Self; -}; - enum EIAPCommand { IAP_PRODUCT_RESULT, @@ -29,7 +19,7 @@ struct DM_ALIGNED(16) IAPCommand } // Used for storing eventual callback info (if needed) - IAPListener m_Callback; + dmScript::LuaCallbackInfo* m_Callback; // THe actual command payload int32_t m_Command; @@ -43,12 +33,6 @@ struct IAPCommandQueue dmMutex::HMutex m_Mutex; }; -void IAP_ClearCallback(IAPListener* callback); -void IAP_RegisterCallback(lua_State* L, int index, IAPListener* callback); -void IAP_UnregisterCallback(IAPListener* callback); -bool IAP_SetupCallback(IAPListener* callback); -bool IAP_CallbackIsValid(IAPListener* callback); - char* IAP_List_CreateBuffer(lua_State* L); void IAP_PushError(lua_State* L, const char* error, int reason); void IAP_PushConstants(lua_State* L);