Moved command queue code to iap_private.h/cpp

This commit is contained in:
mathiaswking 2019-11-14 10:48:19 +01:00
parent 33c5709eaf
commit bca28de29a
3 changed files with 120 additions and 87 deletions

View File

@ -9,22 +9,6 @@
#define LIB_NAME "iap" #define LIB_NAME "iap"
struct IAP;
#define CMD_PRODUCT_RESULT (0)
#define CMD_PURCHASE_RESULT (1)
struct DM_ALIGNED(16) IAPCommand
{
IAPCommand()
{
memset(this, 0, sizeof(IAPCommand));
}
uint32_t m_Command;
int32_t m_ResponseCode;
void* m_Data1;
};
static JNIEnv* Attach() static JNIEnv* Attach()
{ {
JNIEnv* env; JNIEnv* env;
@ -67,27 +51,14 @@ struct IAP
jmethodID m_ProcessPendingConsumables; jmethodID m_ProcessPendingConsumables;
jmethodID m_FinishTransaction; jmethodID m_FinishTransaction;
dmArray<IAPCommand> m_CommandsQueue; IAPCommandQueue m_CommandQueue;
dmMutex::HMutex m_Mutex;
}; };
static IAP g_IAP; static IAP g_IAP;
static void QueueCommand(IAPCommand* cmd) static void ResetCallback(lua_State* L)
{
DM_MUTEX_SCOPED_LOCK(g_IAP.m_Mutex);
if(g_IAP.m_CommandsQueue.Full())
{
g_IAP.m_CommandsQueue.OffsetCapacity(2);
}
g_IAP.m_CommandsQueue.Push(*cmd);
}
static void VerifyCallback(lua_State* L)
{ {
if (g_IAP.m_Callback != LUA_NOREF) { if (g_IAP.m_Callback != LUA_NOREF) {
dmLogError("Unexpected callback set");
dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Callback); dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Callback);
dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Self); dmScript::Unref(L, LUA_REGISTRYINDEX, g_IAP.m_Self);
g_IAP.m_Callback = LUA_NOREF; g_IAP.m_Callback = LUA_NOREF;
@ -99,7 +70,7 @@ static void VerifyCallback(lua_State* L)
static int IAP_List(lua_State* L) static int IAP_List(lua_State* L)
{ {
int top = lua_gettop(L); int top = lua_gettop(L);
VerifyCallback(L); ResetCallback(L);
char* buf = IAP_List_CreateBuffer(L); char* buf = IAP_List_CreateBuffer(L);
if( buf == 0 ) if( buf == 0 )
@ -267,14 +238,14 @@ JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onProductsResult__ILjava_lang_
} }
IAPCommand cmd; IAPCommand cmd;
cmd.m_Command = CMD_PRODUCT_RESULT; cmd.m_Command = IAP_PRODUCT_RESULT;
cmd.m_ResponseCode = responseCode; cmd.m_ResponseCode = responseCode;
if (pl) if (pl)
{ {
cmd.m_Data1 = strdup(pl); cmd.m_Data = strdup(pl);
env->ReleaseStringUTFChars(productList, pl); env->ReleaseStringUTFChars(productList, pl);
} }
QueueCommand(&cmd); IAP_Queue_Push(&g_IAP.m_CommandQueue, &cmd);
} }
JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onPurchaseResult__ILjava_lang_String_2(JNIEnv* env, jobject, jint responseCode, jstring purchaseData) JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onPurchaseResult__ILjava_lang_String_2(JNIEnv* env, jobject, jint responseCode, jstring purchaseData)
@ -286,14 +257,14 @@ JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onPurchaseResult__ILjava_lang_
} }
IAPCommand cmd; IAPCommand cmd;
cmd.m_Command = CMD_PURCHASE_RESULT; cmd.m_Command = IAP_PURCHASE_RESULT;
cmd.m_ResponseCode = responseCode; cmd.m_ResponseCode = responseCode;
if (pd) if (pd)
{ {
cmd.m_Data1 = strdup(pd); cmd.m_Data = strdup(pd);
env->ReleaseStringUTFChars(purchaseData, pd); env->ReleaseStringUTFChars(purchaseData, pd);
} }
QueueCommand(&cmd); IAP_Queue_Push(&g_IAP.m_CommandQueue, &cmd);
} }
#ifdef __cplusplus #ifdef __cplusplus
@ -327,7 +298,7 @@ static void HandleProductResult(const IAPCommand* cmd)
if (cmd->m_ResponseCode == BILLING_RESPONSE_RESULT_OK) { if (cmd->m_ResponseCode == BILLING_RESPONSE_RESULT_OK) {
dmJson::Document doc; dmJson::Document doc;
dmJson::Result r = dmJson::Parse((const char*) cmd->m_Data1, &doc); dmJson::Result r = dmJson::Parse((const char*) cmd->m_Data, &doc);
if (r == dmJson::RESULT_OK && doc.m_NodeCount > 0) { if (r == dmJson::RESULT_OK && doc.m_NodeCount > 0) {
char err_str[128]; char err_str[128];
if (dmScript::JsonToLua(L, &doc, 0, err_str, sizeof(err_str)) < 0) { if (dmScript::JsonToLua(L, &doc, 0, err_str, sizeof(err_str)) < 0) {
@ -390,9 +361,9 @@ static void HandlePurchaseResult(const IAPCommand* cmd)
} }
if (cmd->m_ResponseCode == BILLING_RESPONSE_RESULT_OK) { if (cmd->m_ResponseCode == BILLING_RESPONSE_RESULT_OK) {
if (cmd->m_Data1 != 0) { if (cmd->m_Data != 0) {
dmJson::Document doc; dmJson::Document doc;
dmJson::Result r = dmJson::Parse((const char*) cmd->m_Data1, &doc); dmJson::Result r = dmJson::Parse((const char*) cmd->m_Data, &doc);
if (r == dmJson::RESULT_OK && doc.m_NodeCount > 0) { if (r == dmJson::RESULT_OK && doc.m_NodeCount > 0) {
char err_str[128]; char err_str[128];
if (dmScript::JsonToLua(L, &doc, 0, err_str, sizeof(err_str)) < 0) { if (dmScript::JsonToLua(L, &doc, 0, err_str, sizeof(err_str)) < 0) {
@ -436,8 +407,7 @@ static dmExtension::Result InitializeIAP(dmExtension::Params* params)
// TODO: Life-cycle managaemnt is *budget*. No notion of "static initalization" // TODO: Life-cycle managaemnt is *budget*. No notion of "static initalization"
// Extend extension functionality with per system initalization? // Extend extension functionality with per system initalization?
if (g_IAP.m_InitCount == 0) { if (g_IAP.m_InitCount == 0) {
g_IAP.m_CommandsQueue.SetCapacity(2); IAP_Queue_Create(&g_IAP.m_CommandQueue);
g_IAP.m_Mutex = dmMutex::New();
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;
@ -499,42 +469,35 @@ static dmExtension::Result InitializeIAP(dmExtension::Params* params)
return dmExtension::RESULT_OK; return dmExtension::RESULT_OK;
} }
static dmExtension::Result UpdateIAP(dmExtension::Params* params) static void IAP_OnCommand(IAPCommand* cmd, void*)
{ {
if (g_IAP.m_CommandsQueue.Empty()) switch (cmd->m_Command)
{ {
return dmExtension::RESULT_OK; case IAP_PRODUCT_RESULT:
} HandleProductResult(cmd);
DM_MUTEX_SCOPED_LOCK(g_IAP.m_Mutex);
for(uint32_t i = 0; i != g_IAP.m_CommandsQueue.Size(); ++i)
{
IAPCommand& cmd = g_IAP.m_CommandsQueue[i];
switch (cmd.m_Command)
{
case CMD_PRODUCT_RESULT:
HandleProductResult(&cmd);
break; break;
case CMD_PURCHASE_RESULT: case IAP_PURCHASE_RESULT:
HandlePurchaseResult(&cmd); HandlePurchaseResult(cmd);
break; break;
default: default:
assert(false); assert(false);
} }
if (cmd.m_Data1) { if (cmd->m_Data) {
free(cmd.m_Data1); free(cmd->m_Data);
} }
} }
g_IAP.m_CommandsQueue.SetSize(0);
static dmExtension::Result UpdateIAP(dmExtension::Params* params)
{
IAP_Queue_Flush(&g_IAP.m_CommandQueue, IAP_OnCommand, 0);
return dmExtension::RESULT_OK; return dmExtension::RESULT_OK;
} }
static dmExtension::Result FinalizeIAP(dmExtension::Params* params) static dmExtension::Result FinalizeIAP(dmExtension::Params* params)
{ {
dmMutex::Delete(g_IAP.m_Mutex); IAP_Queue_Destroy(&g_IAP.m_CommandQueue);
--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 (params->m_L == g_IAP.m_Listener.m_L && g_IAP.m_Listener.m_Callback != LUA_NOREF) {

View File

@ -96,4 +96,43 @@ void IAP_PushConstants(lua_State* L)
#undef SETCONSTANT #undef SETCONSTANT
} }
void IAP_Queue_Create(IAPCommandQueue* queue)
{
queue->m_Mutex = dmMutex::New();
}
void IAP_Queue_Destroy(IAPCommandQueue* queue)
{
dmMutex::Delete(queue->m_Mutex);
}
void IAP_Queue_Push(IAPCommandQueue* queue, IAPCommand* cmd)
{
DM_MUTEX_SCOPED_LOCK(queue->m_Mutex);
if(queue->m_Commands.Full())
{
queue->m_Commands.OffsetCapacity(2);
}
queue->m_Commands.Push(*cmd);
}
void IAP_Queue_Flush(IAPCommandQueue* queue, IAPCommandFn fn, void* ctx)
{
assert(fn != 0);
if (queue->m_Commands.Empty())
{
return;
}
DM_MUTEX_SCOPED_LOCK(queue->m_Mutex);
for(uint32_t i = 0; i != queue->m_Commands.Size(); ++i)
{
fn(&queue->m_Commands[i], ctx);
}
queue->m_Commands.SetSize(0);
}
#endif // DM_PLATFORM_HTML5 || DM_PLATFORM_ANDROID || DM_PLATFORM_IOS #endif // DM_PLATFORM_HTML5 || DM_PLATFORM_ANDROID || DM_PLATFORM_IOS

View File

@ -5,6 +5,29 @@
#include <dmsdk/sdk.h> #include <dmsdk/sdk.h>
enum EIAPCommand
{
IAP_PRODUCT_RESULT,
IAP_PURCHASE_RESULT,
};
struct DM_ALIGNED(16) IAPCommand
{
IAPCommand()
{
memset(this, 0, sizeof(IAPCommand));
}
int32_t m_Command;
int32_t m_ResponseCode;
void* m_Data;
};
struct IAPCommandQueue
{
dmArray<IAPCommand> m_Commands;
dmMutex::HMutex m_Mutex;
};
struct IAPListener struct IAPListener
{ {
IAPListener() IAPListener()
@ -23,6 +46,14 @@ char* IAP_List_CreateBuffer(lua_State* L);
void IAP_PushError(lua_State* L, const char* error, int reason); void IAP_PushError(lua_State* L, const char* error, int reason);
void IAP_PushConstants(lua_State* L); void IAP_PushConstants(lua_State* L);
typedef void (*IAPCommandFn)(IAPCommand* cmd, void* ctx);
void IAP_Queue_Create(IAPCommandQueue* queue);
void IAP_Queue_Destroy(IAPCommandQueue* queue);
// The command is copied by value into the queue
void IAP_Queue_Push(IAPCommandQueue* queue, IAPCommand* cmd);
void IAP_Queue_Flush(IAPCommandQueue* queue, IAPCommandFn fn, void* ctx);
#endif #endif
#endif // DM_PLATFORM_HTML5 || DM_PLATFORM_ANDROID || DM_PLATFORM_IOS #endif // DM_PLATFORM_HTML5 || DM_PLATFORM_ANDROID || DM_PLATFORM_IOS