Updated html5 to use the new Lua callback api from dmScript

This commit is contained in:
mathiaswking 2019-11-21 18:06:39 +01:00
parent 4221a3ba27
commit 0e76cd4f24
2 changed files with 89 additions and 152 deletions

View File

@ -31,7 +31,7 @@ var LibraryFacebookIAP = {
FB_PAYMENT_RESPONSE_APPINVALIDITEMPARAM : 1383051 FB_PAYMENT_RESPONSE_APPINVALIDITEMPARAM : 1383051
}, },
http_callback: function(xmlhttp, callback, lua_state, products, product_ids, product_count, url_index, url_count) { http_callback: function(xmlhttp, callback, lua_callback, products, product_ids, product_count, url_index, url_count) {
if (xmlhttp.readyState == 4) { if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) { if(xmlhttp.status == 200) {
var xmlDoc = document.createElement( 'html' ); var xmlDoc = document.createElement( 'html' );
@ -72,11 +72,11 @@ var LibraryFacebookIAP = {
if(url_index == product_count-1) { if(url_index == product_count-1) {
var productsJSON = JSON.stringify(products); var productsJSON = JSON.stringify(products);
var res_buf = allocate(intArrayFromString(productsJSON), 'i8', ALLOC_STACK); var res_buf = allocate(intArrayFromString(productsJSON), 'i8', ALLOC_STACK);
Runtime.dynCall('vii', callback, [lua_state, res_buf]); Runtime.dynCall('vii', callback, [lua_callback, res_buf]);
} else { } else {
var xmlhttp = new XMLHttpRequest(); var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
FBinner.http_callback(xmlhttp, callback, lua_state, products, product_ids, product_count, url_index+1); FBinner.http_callback(xmlhttp, callback, lua_callback, products, product_ids, product_count, url_index+1);
}; };
xmlhttp.open("GET", product_ids[url_index+1], true); xmlhttp.open("GET", product_ids[url_index+1], true);
xmlhttp.send(); xmlhttp.send();
@ -86,7 +86,7 @@ var LibraryFacebookIAP = {
}, },
dmIAPFBList: function(params, callback, lua_state) { dmIAPFBList: function(params, callback, lua_callback) {
var product_ids = Pointer_stringify(params).trim().split(','); var product_ids = Pointer_stringify(params).trim().split(',');
var product_count = product_ids.length; var product_count = product_ids.length;
if(product_count == 0) { if(product_count == 0) {
@ -96,7 +96,7 @@ var LibraryFacebookIAP = {
products = {}; products = {};
var xmlhttp = new XMLHttpRequest(); var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
FBinner.http_callback(xmlhttp, callback, lua_state, products, product_ids, product_count, 0); FBinner.http_callback(xmlhttp, callback, lua_callback, products, product_ids, product_count, 0);
}; };
// chain of async http read of product files // chain of async http read of product files
xmlhttp.open("GET", product_ids[0], true); xmlhttp.open("GET", product_ids[0], true);
@ -104,7 +104,7 @@ var LibraryFacebookIAP = {
}, },
// https://developers.facebook.com/docs/javascript/reference/FB.ui // https://developers.facebook.com/docs/javascript/reference/FB.ui
dmIAPFBBuy: function(param_product_id, param_request_id, callback, lua_state) { dmIAPFBBuy: function(param_product_id, param_request_id, callback, lua_callback) {
var product_id = Pointer_stringify(param_product_id); var product_id = Pointer_stringify(param_product_id);
var buy_params = { var buy_params = {
@ -144,7 +144,7 @@ var LibraryFacebookIAP = {
var productsJSON = JSON.stringify(result) var productsJSON = JSON.stringify(result)
var res_buf = allocate(intArrayFromString(productsJSON), 'i8', ALLOC_STACK); var res_buf = allocate(intArrayFromString(productsJSON), 'i8', ALLOC_STACK);
Runtime.dynCall('viii', callback, [lua_state, res_buf, 0]); Runtime.dynCall('viii', callback, [lua_callback, res_buf, 0]);
} else { } else {
@ -157,7 +157,7 @@ var LibraryFacebookIAP = {
reason = FBinner.BillingResponse.BILLING_RESPONSE_RESULT_ERROR; reason = FBinner.BillingResponse.BILLING_RESPONSE_RESULT_ERROR;
console.log("Unknown response: ", response); console.log("Unknown response: ", response);
} }
Runtime.dynCall('viii', callback, [lua_state, 0, reason]); Runtime.dynCall('viii', callback, [lua_callback, 0, reason]);
} }
} }
); );

View File

@ -15,63 +15,35 @@ struct IAP
IAP() IAP()
{ {
memset(this, 0, sizeof(*this)); 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_autoFinishTransactions = true;
} }
int m_InitCount;
int m_Callback;
int m_Self;
bool m_autoFinishTransactions;
lua_State* m_L;
IAPListener m_Listener;
dmScript::LuaCallbackInfo* m_Listener;
int m_InitCount;
bool m_autoFinishTransactions;
} g_IAP; } g_IAP;
typedef void (*OnIAPFBList)(void *L, const char* json); typedef void (*OnIAPFBList)(void* luacallback, const char* json);
typedef void (*OnIAPFBListenerCallback)(void *L, const char* json, int error_code); typedef void (*OnIAPFBListenerCallback)(void* luacallback, const char* json, int error_code);
extern "C" { extern "C" {
// Implementation in library_facebook_iap.js // Implementation in library_facebook_iap.js
void dmIAPFBList(const char* item_ids, OnIAPFBList callback, lua_State* L); void dmIAPFBList(const char* item_ids, OnIAPFBList callback, dmScript::LuaCallbackInfo* luacallback);
void dmIAPFBBuy(const char* item_id, const char* request_id, OnIAPFBListenerCallback callback, lua_State* L); void dmIAPFBBuy(const char* item_id, const char* request_id, OnIAPFBListenerCallback callback, dmScript::LuaCallbackInfo* luacallback);
} }
static void IAPList_Callback(void* luacallback, const char* result_json)
static void VerifyCallback(lua_State* L)
{ {
if (g_IAP.m_Callback != LUA_NOREF) { dmScript::LuaCallbackInfo* callback = (dmScript::LuaCallbackInfo*)luacallback;
dmLogError("Unexpected callback set"); lua_State* L = dmScript::GetCallbackLuaContext(callback);
dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Callback); DM_LUA_STACK_CHECK(L, 0);
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;
}
}
void IAPList_Callback(void* Lv, const char* result_json) if (!dmScript::SetupCallback(callback))
{
lua_State* L = (lua_State*) Lv;
if (g_IAP.m_Callback != LUA_NOREF) {
int top = lua_gettop(L);
int callback = g_IAP.m_Callback;
lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
// Setup self
lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAP.m_Self);
lua_pushvalue(L, -1);
dmScript::SetInstance(L);
if (!dmScript::IsInstanceValid(L))
{ {
dmLogError("Could not run iap facebook callback because the instance has been deleted."); dmScript::DestroyCallback(callback);
lua_pop(L, 2);
assert(top == lua_gettop(L));
return; return;
} }
if(result_json != 0) if(result_json != 0)
{ {
dmJson::Document doc; dmJson::Document doc;
@ -99,68 +71,42 @@ void IAPList_Callback(void* Lv, const char* result_json)
IAP_PushError(L, "Got empty list result.", REASON_UNSPECIFIED); IAP_PushError(L, "Got empty list result.", REASON_UNSPECIFIED);
} }
int ret = lua_pcall(L, 3, 0, 0); int ret = dmScript::PCall(L, 3, 0);
if (ret != 0) { (void)ret;
dmLogError("Error running callback: %s", lua_tostring(L, -1));
lua_pop(L, 1);
}
assert(top == lua_gettop(L));
dmScript::Unref(L, LUA_REGISTRYINDEX, callback);
g_IAP.m_Callback = LUA_NOREF;
} else {
dmLogError("No callback set");
}
dmScript::DestroyCallback(callback);
dmScript::TeardownCallback(callback);
} }
int IAP_List(lua_State* L) static int IAP_List(lua_State* L)
{ {
int top = lua_gettop(L); DM_LUA_STACK_CHECK(L, 0);
VerifyCallback(L);
char* buf = IAP_List_CreateBuffer(L); char* buf = IAP_List_CreateBuffer(L);
if( buf == 0 ) if( buf == 0 )
{ {
assert(top == lua_gettop(L));
return 0; return 0;
} }
luaL_checktype(L, 2, LUA_TFUNCTION); dmScript::LuaCallbackInfo* callback = dmScript::CreateCallback(L, 2);
lua_pushvalue(L, 2);
g_IAP.m_Callback = dmScript::Ref(L, LUA_REGISTRYINDEX); dmIAPFBList(buf, (OnIAPFBList)IAPList_Callback, callback);
dmScript::GetInstance(L);
g_IAP.m_Self = dmScript::Ref(L, LUA_REGISTRYINDEX);
g_IAP.m_L = dmScript::GetMainThread(L);
dmIAPFBList(buf, (OnIAPFBList)IAPList_Callback, g_IAP.m_L);
free(buf); free(buf);
assert(top == lua_gettop(L));
return 0; return 0;
} }
void IAPListener_Callback(void* Lv, const char* result_json, int error_code) static void IAPListener_Callback(void* luacallback, const char* result_json, int error_code)
{ {
lua_State* L = g_IAP.m_Listener.m_L; dmScript::LuaCallbackInfo* callback = (dmScript::LuaCallbackInfo*)luacallback;
int top = lua_gettop(L); lua_State* L = dmScript::GetCallbackLuaContext(callback);
if (g_IAP.m_Listener.m_Callback == LUA_NOREF) { DM_LUA_STACK_CHECK(L, 0);
dmLogError("No callback set");
return;
}
lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAP.m_Listener.m_Callback);
// Setup self if (!dmScript::SetupCallback(callback))
lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAP.m_Listener.m_Self);
lua_pushvalue(L, -1);
dmScript::SetInstance(L);
if (!dmScript::IsInstanceValid(L))
{ {
dmLogError("Could not run IAP callback because the instance has been deleted.");
lua_pop(L, 2);
assert(top == lua_gettop(L));
return; return;
} }
if (result_json) { if (result_json) {
dmJson::Document doc; dmJson::Document doc;
dmJson::Result r = dmJson::Parse(result_json, &doc); dmJson::Result r = dmJson::Parse(result_json, &doc);
@ -197,21 +143,23 @@ void IAPListener_Callback(void* Lv, const char* result_json, int error_code)
break; break;
} }
} }
int ret = lua_pcall(L, 3, 0, 0);
if (ret != 0) { int ret = dmScript::PCall(L, 3, 0);
dmLogError("Error running callback: %s", lua_tostring(L, -1)); (void)ret;
lua_pop(L, 1);
} dmScript::TeardownCallback(callback);
assert(top == lua_gettop(L));
} }
int IAP_Buy(lua_State* L) static int IAP_Buy(lua_State* L)
{ {
if (g_IAP.m_Listener.m_Callback == LUA_NOREF) { DM_LUA_STACK_CHECK(L, 0);
if (!g_IAP.m_Listener) {
dmLogError("No callback set"); dmLogError("No callback set");
return 0; return 0;
} }
int top = lua_gettop(L); int top = lua_gettop(L);
const char* id = luaL_checkstring(L, 1); const char* id = luaL_checkstring(L, 1);
const char* request_id = 0x0; const char* request_id = 0x0;
@ -224,43 +172,34 @@ int IAP_Buy(lua_State* L)
lua_pop(L, 2); lua_pop(L, 2);
} }
dmIAPFBBuy(id, request_id, (OnIAPFBListenerCallback)IAPListener_Callback, L); dmIAPFBBuy(id, request_id, (OnIAPFBListenerCallback)IAPListener_Callback, g_IAP.m_Listener);
assert(top == lua_gettop(L));
return 0; return 0;
} }
int IAP_SetListener(lua_State* L) static int IAP_SetListener(lua_State* L)
{ {
IAP* iap = &g_IAP; DM_LUA_STACK_CHECK(L, 0);
luaL_checktype(L, 1, LUA_TFUNCTION); if (g_IAP.m_Listener)
lua_pushvalue(L, 1); dmScript::DestroyCallback(g_IAP.m_Listener);
int cb = dmScript::Ref(L, LUA_REGISTRYINDEX); g_IAP.m_Listener = dmScript::CreateCallback(L, 1);
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);
}
iap->m_Listener.m_L = dmScript::GetMainThread(L);
iap->m_Listener.m_Callback = cb;
dmScript::GetInstance(L);
iap->m_Listener.m_Self = dmScript::Ref(L, LUA_REGISTRYINDEX);
return 0; return 0;
} }
int IAP_Finish(lua_State* L) static int IAP_Finish(lua_State* L)
{ {
return 0; return 0;
} }
int IAP_Restore(lua_State* L) static int IAP_Restore(lua_State* L)
{ {
DM_LUA_STACK_CHECK(L, 1);
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
return 1; return 1;
} }
int IAP_GetProviderId(lua_State* L) static int IAP_GetProviderId(lua_State* L)
{ {
DM_LUA_STACK_CHECK(L, 1);
lua_pushinteger(L, PROVIDER_ID_FACEBOOK); lua_pushinteger(L, PROVIDER_ID_FACEBOOK);
return 1; return 1;
} }
@ -276,13 +215,13 @@ static const luaL_reg IAP_methods[] =
{0, 0} {0, 0}
}; };
dmExtension::Result InitializeIAP(dmExtension::Params* params) static dmExtension::Result InitializeIAP(dmExtension::Params* params)
{ {
if (g_IAP.m_InitCount == 0) { if (g_IAP.m_InitCount == 0) {
g_IAP.m_autoFinishTransactions = dmConfigFile::GetInt(params->m_ConfigFile, "iap.auto_finish_transactions", 1) == 1; g_IAP.m_autoFinishTransactions = dmConfigFile::GetInt(params->m_ConfigFile, "iap.auto_finish_transactions", 1) == 1;
} }
g_IAP.m_InitCount++; g_IAP.m_InitCount++;
lua_State*L = params->m_L; lua_State* L = params->m_L;
int top = lua_gettop(L); int top = lua_gettop(L);
luaL_register(L, LIB_NAME, IAP_methods); luaL_register(L, LIB_NAME, IAP_methods);
@ -293,15 +232,13 @@ dmExtension::Result InitializeIAP(dmExtension::Params* params)
return dmExtension::RESULT_OK; return dmExtension::RESULT_OK;
} }
dmExtension::Result FinalizeIAP(dmExtension::Params* params) static dmExtension::Result FinalizeIAP(dmExtension::Params* params)
{ {
--g_IAP.m_InitCount; --g_IAP.m_InitCount;
if (params->m_L == g_IAP.m_Listener.m_L && g_IAP.m_Listener.m_Callback != LUA_NOREF) { if (g_IAP.m_Listener && g_IAP.m_InitCount == 0)
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); dmScript::DestroyCallback(g_IAP.m_Listener);
g_IAP.m_Listener.m_L = 0; g_IAP.m_Listener = 0;
g_IAP.m_Listener.m_Callback = LUA_NOREF;
g_IAP.m_Listener.m_Self = LUA_NOREF;
} }
return dmExtension::RESULT_OK; return dmExtension::RESULT_OK;
} }