mirror of
https://github.com/defold/extension-iap
synced 2025-06-27 10:27:46 +02:00
Moved command queue code to iap_private.h/cpp
This commit is contained in:
parent
33c5709eaf
commit
bca28de29a
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user