#if defined(DM_PLATFORM_HTML5) || defined(DM_PLATFORM_ANDROID) || defined(DM_PLATFORM_IOS)
#include
#include "iap.h"
#include "iap_private.h"
#include
#include
// 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)
{
int top = lua_gettop(L);
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushnil(L);
int length = 0;
while (lua_next(L, 1) != 0) {
if (length > 0) {
++length;
}
const char* p = lua_tostring(L, -1);
if(!p)
{
luaL_error(L, "IAP: Failed to get value (string) from table");
}
length += strlen(p);
lua_pop(L, 1);
}
char* buf = (char*)malloc(length+1);
if( buf == 0 )
{
dmLogError("Could not allocate buffer of size %d", length+1);
assert(top == lua_gettop(L));
return 0;
}
buf[0] = '\0';
int i = 0;
lua_pushnil(L);
while (lua_next(L, 1) != 0) {
if (i > 0) {
dmStrlCat(buf, ",", length+1);
}
const char* p = lua_tostring(L, -1);
if(!p)
{
luaL_error(L, "IAP: Failed to get value (string) from table");
}
dmStrlCat(buf, p, length+1);
lua_pop(L, 1);
++i;
}
assert(top == lua_gettop(L));
return buf;
}
void IAP_PushError(lua_State* L, const char* error, int reason)
{
if (error != 0) {
lua_newtable(L);
lua_pushstring(L, "error");
lua_pushstring(L, error);
lua_rawset(L, -3);
lua_pushstring(L, "reason");
lua_pushnumber(L, reason);
lua_rawset(L, -3);
} else {
lua_pushnil(L);
}
}
void IAP_PushConstants(lua_State* L)
{
#define SETCONSTANT(name) \
lua_pushnumber(L, (lua_Number) name); \
lua_setfield(L, -2, #name);\
SETCONSTANT(TRANS_STATE_PURCHASING)
SETCONSTANT(TRANS_STATE_PURCHASED)
SETCONSTANT(TRANS_STATE_FAILED)
SETCONSTANT(TRANS_STATE_RESTORED)
SETCONSTANT(TRANS_STATE_UNVERIFIED)
SETCONSTANT(REASON_UNSPECIFIED)
SETCONSTANT(REASON_USER_CANCELED)
SETCONSTANT(PROVIDER_ID_GOOGLE)
SETCONSTANT(PROVIDER_ID_AMAZON)
SETCONSTANT(PROVIDER_ID_APPLE)
SETCONSTANT(PROVIDER_ID_FACEBOOK)
#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;
}
dmArray tmp;
{
DM_MUTEX_SCOPED_LOCK(queue->m_Mutex);
tmp.Swap(queue->m_Commands);
}
for(uint32_t i = 0; i != tmp.Size(); ++i)
{
fn(&tmp[i], ctx);
}
}
#endif // DM_PLATFORM_HTML5 || DM_PLATFORM_ANDROID || DM_PLATFORM_IOS