Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Commit

Permalink
[[ ExternalsApiV5 ]] Added referencing comments to engine-side changes.
Browse files Browse the repository at this point in the history
[[ ExternalsApiV5 ]] Added mainthread check for MCNotifyPush() on Windows.
[[ ExternalsApiV5 ]] Added implementation of MCUIDC::pingwait() on Desktop platforms using MCNotifyPing().
  • Loading branch information
runrevmark committed Jun 14, 2013
1 parent f363f33 commit 5669275
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 28 deletions.
51 changes: 44 additions & 7 deletions engine/src/externalv1.cpp
Expand Up @@ -52,6 +52,7 @@ typedef uint32_t MCExternalRunOnMainThreadOptions;
typedef void (*MCExternalThreadOptionalCallback)(void *state);
typedef void (*MCExternalThreadRequiredCallback)(void *state, int flags);

// MW-2013-06-14: [[ ExternalsApiV5 ]] Update the interface version.
#define kMCExternalInterfaceVersion 5

enum
Expand Down Expand Up @@ -178,6 +179,7 @@ enum MCExternalContextQueryTag
kMCExternalContextQueryDefaultStack,
kMCExternalContextQueryDefaultCard,

// MW-2013-06-14: [[ ExternalsApiV5 ]] Accessor to fetch 'the wholeMatches'.
kMCExternalContextQueryWholeMatches,
};

Expand All @@ -188,7 +190,13 @@ enum MCExternalVariableQueryTag
kMCExternalVariableQueryFormat,
kMCExternalVariableQueryRetention,
kMCExternalVariableQueryIsAnArray,

// MW-2013-06-14: [[ ExternalsApiV5 ]] Accessor to determine if a variable
// is a 1-based, dense, numerically keyed array (aka a sequence).
kMCExternalVariableQueryIsASequence, // V5

// MW-2013-06-14: [[ ExternalsApiV5 ]] Accessor to determine if a variable
// is empty.
kMCExternalVariableQueryIsEmpty, // V5
};

Expand All @@ -199,7 +207,13 @@ enum MCExternalInterfaceQueryTag
kMCExternalInterfaceQueryViewController = 3,
kMCExternalInterfaceQueryActivity = 4, // V4
kMCExternalInterfaceQueryContainer = 5, // V4

// MW-2013-06-14: [[ ExternalsApiV5 ]] Accessor to get the JavaEnv for the
// script thread.
kMCExternalInterfaceQueryScriptJavaEnv = 6, // V5

// MW-2013-06-14: [[ ExternalsApiV5 ]] Accessor to get the JavaEnv for the
// system thread.
kMCExternalInterfaceQuerySystemJavaEnv = 7, // V5
};

Expand Down Expand Up @@ -308,8 +322,13 @@ struct MCExternalInterface

/////////

MCExternalError (*context_evaluate)(const char *p_expression, unsigned int options, MCExternalVariableRef value); // V5
MCExternalError (*context_execute)(const char *p_expression, unsigned int options); // V5
// MW-2013-06-14: [[ ExternalsApiV5 ]] Method to evaluate the given expression
// in the current context.
MCExternalError (*context_evaluate)(const char *p_expression, unsigned int options, MCExternalVariableRef value, ...); // V5

// MW-2013-06-14: [[ ExternalsApiV5 ]] Method to execute the given expression
// in the current context.
MCExternalError (*context_execute)(const char *p_expression, unsigned int options, ...); // V5
};

typedef MCExternalInfo *(*MCExternalDescribeProc)(void);
Expand Down Expand Up @@ -890,6 +909,8 @@ static MCExternalError MCExternalEngineRunOnMainThread(void *p_callback, void *p
static MCExternalError MCExternalEngineRunOnMainThread(void *p_callback, void *p_callback_state, MCExternalRunOnMainThreadOptions p_options)
{
#if defined(_DESKTOP)
// MW-2013-06-14: [[ ExternalsApiV5 ]] Pass the correct parameters through
// to MCNotifyPush so that LCObjectPost works.
if (!MCNotifyPush((MCExternalThreadOptionalCallback)p_callback, p_callback_state, (p_options & kMCExternalRunOnMainThreadPost) == 0, (p_options & kMCExternalRunOnMainThreadSafe) != 0))
return kMCExternalErrorOutOfMemory;

Expand Down Expand Up @@ -940,6 +961,7 @@ static MCExternalError MCExternalContextQuery(MCExternalContextQueryTag op, void
case kMCExternalContextQueryConvertOctals:
*(bool *)result = MCEPptr -> getconvertoctals() == True;
break;
// MW-2013-06-13: [[ ExternalsApiV5 ]] Implementation of 'the wholeMatches' query.
case kMCExternalContextQueryWholeMatches:
*(bool *)result = MCEPptr -> getwholematches() == True;
break;
Expand Down Expand Up @@ -985,7 +1007,8 @@ static MCExternalError MCExternalContextQuery(MCExternalContextQueryTag op, void
return kMCExternalErrorNone;
}

MCExternalError MCExternalContextEvaluate(const char *p_expression, unsigned int p_options, MCExternalVariableRef p_result)
// MW-2013-06-13: [[ ExternalsApiV5 ]] Implementation of context_evaluate method.
MCExternalError MCExternalContextEvaluate(const char *p_expression, unsigned int p_options, MCExternalVariableRef p_result, ...)
{
MCEPptr -> setsvalue(p_expression);

Expand All @@ -1003,7 +1026,8 @@ MCExternalError MCExternalContextEvaluate(const char *p_expression, unsigned int
return kMCExternalErrorNone;
}

MCExternalError MCExternalContextExecute(const char *p_commands, unsigned int p_options)
// MW-2013-06-13: [[ ExternalsApiV5 ]] Implementation of context_execute method.
MCExternalError MCExternalContextExecute(const char *p_commands, unsigned int p_options, ...)
{
MCEPptr -> setsvalue(p_commands);

Expand Down Expand Up @@ -1098,12 +1122,17 @@ static MCExternalError MCExternalVariableQuery(MCExternalVariableRef var, MCExte
case kMCExternalVariableQueryIsAnArray:
*(bool *)r_result = var -> is_empty() || var -> is_array();
break;

// MW-2013-06-13: [[ ExternalsApiV5 ]] Implementation of IsEmpty variable query.
case kMCExternalVariableQueryIsEmpty:
*(bool *)r_result = var -> is_empty();
break;

// MW-2013-06-13: [[ ExternalsApiV5 ]] Implementation of IsASequence variable query.
case kMCExternalVariableQueryIsASequence:
*(bool *)r_result = var -> is_array() && var -> get_array() -> issequence();
break;

default:
return kMCExternalErrorInvalidVariableQuery;
}
Expand Down Expand Up @@ -1912,10 +1941,9 @@ static MCExternalError MCExternalWaitRun(void *unused, unsigned int p_options)

static MCExternalError MCExternalWaitBreak(void *unused, unsigned int p_options)
{
#ifdef TARGET_SUBPLATFORM_IPHONE
// MW-2011-08-16: [[ Wait ]] Tell the wait to look for more stuff to do/exit.
// MW-2013-06-14: [[ ExternalsApiV5 ]] Do a pingwait() on all platforms (still
// needs implemented on Desktop).
MCscreen -> pingwait();
#endif
return kMCExternalErrorNone;
}

Expand All @@ -1926,6 +1954,8 @@ extern void *MCIPhoneGetViewController(void);
extern float MCIPhoneGetResolutionScale(void);
extern void *MCAndroidGetActivity(void);
extern void *MCAndroidGetContainer(void);

// MW-2013-06-13: [[ ExternalsApiV5 ]] Methods to get the JavaEnv's.
extern void *MCAndroidGetScriptJavaEnv(void);
extern void *MCAndroidGetSystemJavaEnv(void);

Expand Down Expand Up @@ -1956,12 +1986,17 @@ static MCExternalError MCExternalInterfaceQuery(MCExternalInterfaceQueryTag op,
case kMCExternalInterfaceQueryContainer:
*(void **)r_value = MCAndroidGetContainer();
break;

// MW-2013-06-13: [[ ExternalsApiV5 ]] Implementation of the script JavaEnv accessor.
case kMCExternalInterfaceQueryScriptJavaEnv:
*(void **)r_value = MCAndroidGetScriptJavaEnv();
break;

// MW-2013-06-13: [[ ExternalsApiV5 ]] Implementation of the systen JavaEnv accessor.
case kMCExternalInterfaceQuerySystemJavaEnv:
*(void **)r_value = MCAndroidGetSystemJavaEnv();
break;

default:
return kMCExternalErrorInvalidInterfaceQuery;
}
Expand Down Expand Up @@ -2013,6 +2048,8 @@ MCExternalInterface g_external_interface =

MCExternalObjectUpdate,

// MW-2013-06-13: [[ ExternalsApiV5 ]] Declare the evaluate and execute methods
// for the outside world.
MCExternalContextEvaluate,
MCExternalContextExecute,
};
Expand Down
14 changes: 14 additions & 0 deletions engine/src/mblandroiddc.cpp
Expand Up @@ -1452,6 +1452,20 @@ void *MCAndroidGetContainer(void)
return (void *)s_android_container;
}

// MW-2013-06-14: [[ ExternalsApiV5 ]] Return the JavaEnv of the Android system
// thread.
void *MCAndroidGetSystemJavaEnv(void)
{
return s_android_ui_env;
}

// MW-2013-06-14: [[ ExternalsApiV5 ]] Return the JavaEnv of the engine's script
// thread.
void *MCAndroidGetScriptJavaEnv(void)
{
return s_java_env;
}

////////////////////////////////////////////////////////////////////////////////

extern "C" JNIEXPORT void JNICALL Java_com_runrev_android_Engine_doCreate(JNIEnv *env, jobject object, jobject activity, jobject container, jobject view) __attribute__((visibility("default")));
Expand Down
49 changes: 28 additions & 21 deletions engine/src/notify.cpp
Expand Up @@ -65,6 +65,7 @@ static bool s_shutting_down = false;
#if defined(_WINDOWS)
HANDLE g_notify_wakeup = NULL;
static CRITICAL_SECTION s_notify_lock;
static DWORD s_main_thread_id = 0;
#elif defined(_MACOSX)
static bool s_notify_sent = false;
static pthread_mutex_t s_notify_lock;
Expand Down Expand Up @@ -177,7 +178,7 @@ static void MCNotifyUnlock(void)
static bool MCNotifyIsMainThread(void)
{
#if defined(_WINDOWS)
return true; // not implemented yet
return GetCurrentThreadId() == s_main_thread_id;
#elif defined(_MACOSX) || defined(_LINUX)
return pthread_self() == s_main_thread;
#endif
Expand All @@ -203,6 +204,7 @@ bool MCNotifyInitialize(void)
#if defined(_WINDOWS)
g_notify_wakeup = CreateEvent(NULL, FALSE, FALSE, NULL);
InitializeCriticalSection(&s_notify_lock);
s_main_thread_id = GetCurrentThreadId();
#elif defined(_MACOSX)
static EventTypeSpec t_events[] = { 'revo', 'wkup' };
::InstallApplicationEventHandler(MCNotifyEventHandler, 1, t_events, NULL, NULL);
Expand Down Expand Up @@ -326,26 +328,7 @@ bool MCNotifyPush(void (*p_callback)(void *), void *p_state, bool p_block, bool

// Ping the main thread to make sure it knows to check for a shiny new
// thing.
#if defined(_WINDOWS)
SetEvent(g_notify_wakeup);
#elif defined(_MACOSX)
if (!s_notify_sent)
{
s_notify_sent = true;
EventRef t_event;
::CreateEvent(NULL, 'revo', 'wkup', 0, kEventAttributeNone, &t_event);
::PostEventToQueue(::GetMainEventQueue(), t_event, p_block ? kEventPriorityHigh : kEventPriorityStandard);
::ReleaseEvent(t_event);
}
#elif defined(_LINUX)
if (!s_notify_sent)
{
s_notify_sent = true;
char t_notify_char = 1;
write(g_notify_pipe[1], &t_notify_char, 1);
}
#endif

MCNotifyPing(p_block);
}
else
t_success = false;
Expand Down Expand Up @@ -429,3 +412,27 @@ bool MCNotifyDispatch(bool p_safe)

return t_dispatched;
}

// MW-2013-06-14: [[ ExternalsApiV5 ]] Wake up the event loop.
void MCNotifyPing(bool p_high_priority)
{
#if defined(_WINDOWS)
SetEvent(g_notify_wakeup);
#elif defined(_MACOSX)
if (!s_notify_sent)
{
s_notify_sent = true;
EventRef t_event;
::CreateEvent(NULL, 'revo', 'wkup', 0, kEventAttributeNone, &t_event);
::PostEventToQueue(::GetMainEventQueue(), t_event, p_high_priority ? kEventPriorityHigh : kEventPriorityStandard);
::ReleaseEvent(t_event);
}
#elif defined(_LINUX)
if (!s_notify_sent)
{
s_notify_sent = true;
char t_notify_char = 1;
write(g_notify_pipe[1], &t_notify_char, 1);
}
#endif
}
3 changes: 3 additions & 0 deletions engine/src/notify.h
Expand Up @@ -28,4 +28,7 @@ bool MCNotifyPush(void (*callback)(void *), void *state, bool block, bool safe);
// otherwise only ones which are for non-script safe points will be.
bool MCNotifyDispatch(bool safe);

// MW-2013-06-14: [[ ExternalsApiV5 ]] Wake up any currently running 'wait'.
void MCNotifyPing(bool p_high_priority);

#endif
6 changes: 6 additions & 0 deletions engine/src/uidc.cpp
Expand Up @@ -40,6 +40,7 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
#include "printer.h"
#include "osspec.h"
#include "redraw.h"
#include "notify.h"

class MCNullPrinter: public MCPrinter
{
Expand Down Expand Up @@ -745,6 +746,11 @@ Boolean MCUIDC::wait(real8 duration, Boolean dispatch, Boolean anyevent)

void MCUIDC::pingwait(void)
{
#ifdef _DESKTOP
// MW-2013-06-14: [[ ExternalsApiV5 ]] Use the notify mechanism to wake up
// any running wait.
MCNotifyPing(false);
#endif
}

void MCUIDC::flushevents(uint2 e)
Expand Down

0 comments on commit 5669275

Please sign in to comment.