Skip to content

Commit

Permalink
Merge pull request #3 from defold/dev-1.2.164
Browse files Browse the repository at this point in the history
Added a command queue on iOS and changed to the new callback functions
  • Loading branch information
britzl authored Nov 25, 2019
2 parents 6814429 + 67f2e9a commit 4fbf046
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 317 deletions.
1 change: 1 addition & 0 deletions extension-iac/src/iac.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#if defined(DM_PLATFORM_ANDROID) || defined(DM_PLATFORM_IOS)

#include "iac.h"

// Extension internal platform specific functions
Expand Down
204 changes: 47 additions & 157 deletions extension-iac/src/iac_android.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
#if defined(DM_PLATFORM_ANDROID)

#include <jni.h>
#include <stdlib.h>

#include "iac.h"
#include "iac_private.h"

#define CMD_INVOKE 1

struct IACCommand
{
IACCommand()
{
memset(this, 0, sizeof(IACCommand));
}
uint8_t m_Type;
const char* m_Payload;
const char* m_Origin;
};

static JNIEnv* Attach()
{
Expand All @@ -29,79 +19,14 @@ static void Detach()
dmGraphics::GetNativeAndroidJavaVM()->DetachCurrentThread();
}

struct IACInvocation
{
IACInvocation()
{
memset(this, 0x0, sizeof(IACInvocation));
}

bool Get(const char** payload, const char** origin)
{
if(!m_Pending)
return false;
m_Pending = false;
*payload = m_Payload;
*origin = m_Origin;
return true;
}

void Store(const char* payload, const char* origin)
{
Release();
if(payload)
{
m_Payload = strdup(payload);
m_Pending = true;
}
if(origin)
{
m_Origin = strdup(origin);
m_Pending = true;
}
}

void Release()
{
if(m_Payload)
free((void*)m_Payload);
if(m_Origin)
free((void*)m_Origin);
memset(this, 0x0, sizeof(IACInvocation));
}

const char* m_Payload;
const char* m_Origin;
bool m_Pending;
};

struct IACListener
{
IACListener()
{
m_L = 0;
m_Callback = LUA_NOREF;
m_Self = LUA_NOREF;
}
lua_State* m_L;
int m_Callback;
int m_Self;
};

struct IAC
{
IAC()
{
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;
}
int m_Callback;
int m_Self;
lua_State* m_L;
IACListener m_Listener;
dmScript::LuaCallbackInfo* m_Listener;

jobject m_IAC;
jobject m_IACJNI;
Expand All @@ -110,28 +35,21 @@ struct IAC

IACInvocation m_StoredInvocation;

dmMutex::HMutex m_Mutex;
dmArray<IACCommand> m_CmdQueue;
IACCommandQueue m_CmdQueue;
};

static IAC g_IAC;


static void OnInvocation(const char* payload, const char *origin)
{
lua_State* L = g_IAC.m_Listener.m_L;
int top = lua_gettop(L);
lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAC.m_Listener.m_Callback);
IAC* iac = &g_IAC;

// Setup self
lua_rawgeti(L, LUA_REGISTRYINDEX, g_IAC.m_Listener.m_Self);
lua_pushvalue(L, -1);
dmScript::SetInstance(L);
lua_State* L = dmScript::GetCallbackLuaContext(iac->m_Listener);
int top = lua_gettop(L);

if (!dmScript::IsInstanceValid(L))
if (!dmScript::SetupCallback(iac->m_Listener))
{
dmLogError("Could not run iac callback because the instance has been deleted.");
lua_pop(L, 2);
assert(top == lua_gettop(L));
return;
}
Expand All @@ -148,26 +66,20 @@ static void OnInvocation(const char* payload, const char *origin)
dmLogError("Error running iac callback: %s", lua_tostring(L, -1));
lua_pop(L, 1);
}

dmScript::TeardownCallback(iac->m_Listener);
assert(top == lua_gettop(L));
}


int IAC_PlatformSetListener(lua_State* L)
{
IAC* iac = &g_IAC;
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_pushvalue(L, 1);
int cb = dmScript::Ref(L, LUA_REGISTRYINDEX);

if (iac->m_Listener.m_Callback != LUA_NOREF) {
dmScript::Unref(iac->m_Listener.m_L, LUA_REGISTRYINDEX, iac->m_Listener.m_Callback);
dmScript::Unref(iac->m_Listener.m_L, LUA_REGISTRYINDEX, iac->m_Listener.m_Self);
}
if (iac->m_Listener)
dmScript::DestroyCallback(iac->m_Listener);

iac->m_Listener.m_L = dmScript::GetMainThread(L);
iac->m_Listener.m_Callback = cb;
dmScript::GetInstance(L);
iac->m_Listener.m_Self = dmScript::Ref(L, LUA_REGISTRYINDEX);
iac->m_Listener = dmScript::CreateCallback(L, 1);

// handle stored invocation
const char* payload, *origin;
Expand All @@ -178,16 +90,20 @@ int IAC_PlatformSetListener(lua_State* L)
}


static void QueueCommand(IACCommand* cmd)

static void HandleInvocation(const IACCommand* cmd)
{
DM_MUTEX_SCOPED_LOCK(g_IAC.m_Mutex);
if (g_IAC.m_CmdQueue.Full())
if (!g_IAC.m_Listener)
{
g_IAC.m_StoredInvocation.Store(cmd->m_Payload, cmd->m_Origin);
}
else
{
g_IAC.m_CmdQueue.OffsetCapacity(8);
OnInvocation(cmd->m_Payload, cmd->m_Origin);
}
g_IAC.m_CmdQueue.Push(*cmd);
}


static const char* StrDup(JNIEnv* env, jstring s)
{
if (s != NULL)
Expand All @@ -211,10 +127,10 @@ extern "C" {
JNIEXPORT void JNICALL Java_com_defold_iac_IACJNI_onInvocation(JNIEnv* env, jobject, jstring jpayload, jstring jorigin)
{
IACCommand cmd;
cmd.m_Type = CMD_INVOKE;
cmd.m_Command = IAC_INVOKE;
cmd.m_Payload = StrDup(env, jpayload);
cmd.m_Origin = StrDup(env, jorigin);
QueueCommand(&cmd);
IAC_Queue_Push(&g_IAC.m_CmdQueue, &cmd);
}

#ifdef __cplusplus
Expand All @@ -224,8 +140,7 @@ JNIEXPORT void JNICALL Java_com_defold_iac_IACJNI_onInvocation(JNIEnv* env, jobj

dmExtension::Result AppInitializeIAC(dmExtension::AppParams* params)
{
g_IAC.m_Mutex = dmMutex::New();
g_IAC.m_CmdQueue.SetCapacity(8);
IAC_Queue_Create(&g_IAC.m_CmdQueue);

JNIEnv* env = Attach();

Expand Down Expand Up @@ -268,10 +183,8 @@ dmExtension::Result AppFinalizeIAC(dmExtension::AppParams* params)
Detach();
g_IAC.m_IAC = NULL;
g_IAC.m_IACJNI = NULL;
g_IAC.m_L = 0;
g_IAC.m_Callback = LUA_NOREF;
g_IAC.m_Self = LUA_NOREF;
dmMutex::Delete(g_IAC.m_Mutex);
g_IAC.m_Listener = 0;
IAC_Queue_Destroy(&g_IAC.m_CmdQueue);
return dmExtension::RESULT_OK;
}

Expand All @@ -284,59 +197,36 @@ dmExtension::Result InitializeIAC(dmExtension::Params* params)

dmExtension::Result FinalizeIAC(dmExtension::Params* params)
{
if (params->m_L == g_IAC.m_Listener.m_L && g_IAC.m_Listener.m_Callback != LUA_NOREF) {
dmScript::Unref(g_IAC.m_Listener.m_L, LUA_REGISTRYINDEX, g_IAC.m_Listener.m_Callback);
dmScript::Unref(g_IAC.m_Listener.m_L, LUA_REGISTRYINDEX, g_IAC.m_Listener.m_Self);
g_IAC.m_Listener.m_L = 0;
g_IAC.m_Listener.m_Callback = LUA_NOREF;
g_IAC.m_Listener.m_Self = LUA_NOREF;
if (params->m_L == dmScript::GetCallbackLuaContext(g_IAC.m_Listener)) {
dmScript::DestroyCallback(g_IAC.m_Listener);
g_IAC.m_Listener = 0;
}
return dmIAC::Finalize(params);
}


dmExtension::Result UpdateIAC(dmExtension::Params* params)
static void IAC_OnCommand(IACCommand* cmd, void*)
{
if (g_IAC.m_CmdQueue.Empty())
switch (cmd->m_Command)
{
return dmExtension::RESULT_OK;
}
case IAC_INVOKE:
HandleInvocation(cmd);
break;

DM_MUTEX_SCOPED_LOCK(g_IAC.m_Mutex);
default:
assert(false);
}

for (uint32_t i=0;i!=g_IAC.m_CmdQueue.Size();i++)
{
IACCommand& cmd = g_IAC.m_CmdQueue[i];

switch (cmd.m_Type)
{
case CMD_INVOKE:
{
if (g_IAC.m_Listener.m_Callback == LUA_NOREF)
{
dmLogError("No iac listener set. Invocation discarded.");
g_IAC.m_StoredInvocation.Store(cmd.m_Payload, cmd.m_Origin);
}
else
{
OnInvocation(cmd.m_Payload, cmd.m_Origin);
}
}
break;
}
if (cmd.m_Payload != 0x0)
{
free((void*)cmd.m_Payload);
cmd.m_Payload = 0x0;
}
if (cmd.m_Origin != 0x0)
{
free((void*)cmd.m_Origin);
cmd.m_Origin = 0x0;
}
if (cmd->m_Payload) {
free((void*)cmd->m_Payload);
}
if (cmd->m_Origin) {
free((void*)cmd->m_Origin);
}
g_IAC.m_CmdQueue.SetSize(0);
}

dmExtension::Result UpdateIAC(dmExtension::Params* params)
{
IAC_Queue_Flush(&g_IAC.m_CmdQueue, IAC_OnCommand, 0);
return dmExtension::RESULT_OK;
}

Expand Down
Loading

0 comments on commit 4fbf046

Please sign in to comment.