Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 64b9206

Browse files
committed
[[ ExternalsApiV5 ]] Merged in Monte's instanceOf based approach to Send/Post parameters.
[[ ExternalsApiV5 ]] Added simple Send/Post test to android test external. [[ ExternalsApiV5 ]] Changed signature of LC.Object.Send/Post to use variadic parameters (Object...).
2 parents d2fc2b3 + 2992dd6 commit 64b9206

File tree

6 files changed

+306
-21
lines changed

6 files changed

+306
-21
lines changed

lcidlc/src/InterfaceGenerate.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,8 +1631,8 @@ static bool InterfaceGenerateExports(InterfaceRef self, CoderRef p_coder)
16311631
{ "ObjectRetain", "void", "jlong object", "object" },
16321632
{ "ObjectRelease", "void", "jlong object", "object" },
16331633
{ "ObjectExists", "jboolean", "jlong object", "object" },
1634-
{ "ObjectSend", "void", "jlong object, jobject message, jobject signature, jobject arguments", "object, message, signature, arguments" },
1635-
{ "ObjectPost", "void", "jlong object, jobject message, jobject signature, jobject arguments", "object, message, signature, arguments" },
1634+
{ "ObjectSend", "void", "jlong object, jobject message, jobjectArray arguments", "object, message, arguments" },
1635+
{ "ObjectPost", "void", "jlong object, jobject message, jobjectArray arguments", "object, message, arguments" },
16361636
{ "ContextMe", "jlong", nil, nil },
16371637
{ "ContextTarget", "jlong", nil, nil },
16381638
{ "RunOnSystemThread", "void", "jobject runnable", "runnable" },

lcidlc/src/Support.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,16 @@ public boolean Exists()
171171

172172
//////////
173173

174-
public void Post(String p_message, String p_signature, java.lang.Object[] p_arguments)
174+
public void Send(String p_message, java.lang.Object... p_arguments)
175175
{
176176
Check();
177-
__ObjectPost(m_pointer, p_message, p_signature, p_arguments);
177+
__ObjectSend(m_pointer, p_message, p_arguments);
178+
}
179+
180+
public void Post(String p_message, java.lang.Object... p_arguments)
181+
{
182+
Check();
183+
__ObjectPost(m_pointer, p_message, p_arguments);
178184
}
179185

180186
//////////
@@ -328,8 +334,8 @@ private static EngineApi getEngineApi()
328334
private static native void __ObjectRetain(long object);
329335
private static native void __ObjectRelease(long object);
330336
private static native boolean __ObjectExists(long object);
331-
private static native void __ObjectSend(long object, String message, String signature, java.lang.Object[] arguments);
332-
private static native void __ObjectPost(long object, String message, String signature, java.lang.Object[] arguments);
337+
private static native void __ObjectSend(long object, String message, java.lang.Object[] arguments);
338+
private static native void __ObjectPost(long object, String message, java.lang.Object[] arguments);
333339
/*private static native java.lang.Object __ObjectGet(long object, int options, String property, String key);
334340
private static native void __ObjectSet(long object, int options, String property, String key);*/
335341

lcidlc/src/Support.mm

Lines changed: 281 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3114,7 +3114,182 @@ static jboolean java_lcapi_ObjectExists(JNIEnv *env, jlong object)
31143114
return t_exists;
31153115
}
31163116

3117-
static void java_lcapi_ObjectSend(JNIEnv *env, jlong object, jobject message, jobject signature, jobject arguments)
3117+
static LCError java_lcapi_LCCreateArguments(JNIEnv *env, jobjectArray arguments, MCVariableRef*& r_argv, uint32_t& r_argc)
3118+
{
3119+
LCError t_error;
3120+
t_error = kLCErrorNone;
3121+
3122+
uint32_t t_argc;
3123+
t_argc = env->GetArrayLength(arguments);
3124+
3125+
MCVariableRef *t_argv;
3126+
3127+
if (t_error == kLCErrorNone)
3128+
{
3129+
t_argv = nil;
3130+
t_argv = (MCVariableRef *)calloc(t_argc, sizeof(MCVariableRef));
3131+
if (t_argv == nil)
3132+
return kLCErrorOutOfMemory;
3133+
}
3134+
3135+
// Get all the classes we want to support
3136+
3137+
jclass t_class_String;
3138+
3139+
if (t_error == kLCErrorNone)
3140+
{
3141+
t_class_String = nil;
3142+
t_class_String = env->FindClass("java/lang/String");
3143+
if (t_class_String == nil)
3144+
t_error = kLCErrorFailed;
3145+
}
3146+
3147+
jclass t_class_Boolean;
3148+
3149+
if (t_error == kLCErrorNone)
3150+
{
3151+
t_class_Boolean = nil;
3152+
t_class_Boolean = env->FindClass("java/lang/Boolean");
3153+
if (t_class_Boolean == nil)
3154+
t_error = kLCErrorFailed;
3155+
}
3156+
3157+
jclass t_class_Integer;
3158+
3159+
if (t_error == kLCErrorNone)
3160+
{
3161+
t_class_Integer = nil;
3162+
t_class_Integer = env->FindClass("java/lang/Integer");
3163+
if (t_class_Integer == nil)
3164+
t_error = kLCErrorFailed;
3165+
}
3166+
3167+
jclass t_class_Double;
3168+
3169+
if (t_error == kLCErrorNone)
3170+
{
3171+
t_class_Double = nil;
3172+
t_class_Double = env->FindClass("java/lang/Double");
3173+
if (t_class_Double == nil)
3174+
t_error = kLCErrorFailed;
3175+
}
3176+
3177+
jclass t_class_ByteBuffer;
3178+
3179+
if (t_error == kLCErrorNone)
3180+
{
3181+
t_class_ByteBuffer = nil;
3182+
t_class_ByteBuffer = env->FindClass("java/nio/ByteBuffer");
3183+
if (t_class_ByteBuffer == nil)
3184+
t_error = kLCErrorFailed;
3185+
}
3186+
3187+
// Get all the required methods so we don't need to get them multiple times
3188+
3189+
jmethodID t_mid_Boolean_booleanValue;
3190+
3191+
if (t_error == kLCErrorNone)
3192+
{
3193+
t_mid_Boolean_booleanValue = nil;
3194+
t_mid_Boolean_booleanValue = env->GetMethodID(t_class_Boolean, "booleanValue", "()Z");
3195+
if (t_mid_Boolean_booleanValue == nil)
3196+
t_error = kLCErrorFailed;
3197+
}
3198+
3199+
jmethodID t_mid_Integer_integerValue;
3200+
3201+
if (t_error == kLCErrorNone)
3202+
{
3203+
t_mid_Integer_integerValue = nil;
3204+
t_mid_Integer_integerValue = env->GetMethodID(t_class_Integer, "intValue", "()I");
3205+
if (t_mid_Integer_integerValue == nil)
3206+
t_error = kLCErrorFailed;
3207+
}
3208+
3209+
jmethodID t_mid_Double_doubleValue;
3210+
3211+
if (t_error == kLCErrorNone)
3212+
{
3213+
t_mid_Double_doubleValue = nil;
3214+
t_mid_Double_doubleValue = env->GetMethodID(t_class_Double, "doubleValue", "()D");
3215+
if (t_mid_Double_doubleValue == nil)
3216+
t_error = kLCErrorFailed;
3217+
}
3218+
3219+
jmethodID t_mid_ByteBuffer_array;
3220+
3221+
if (t_error == kLCErrorNone)
3222+
{
3223+
t_mid_ByteBuffer_array = nil;
3224+
t_mid_ByteBuffer_array = env->GetMethodID(t_class_ByteBuffer, "array", "()[B");
3225+
if (t_mid_ByteBuffer_array == nil)
3226+
t_error = kLCErrorFailed;
3227+
}
3228+
3229+
for (uint32_t i = 0; i < t_argc; i++)
3230+
{
3231+
t_error = (LCError)MCVariableCreate(&t_argv[i]);
3232+
if (t_error != kLCErrorNone)
3233+
break;
3234+
3235+
jobject t_param;
3236+
if (t_error == kLCErrorNone)
3237+
{
3238+
t_param = nil;
3239+
t_param = env->GetObjectArrayElement(arguments,i);
3240+
if (t_param == nil)
3241+
t_error = kLCErrorFailed;
3242+
}
3243+
3244+
if (t_error == kLCErrorNone)
3245+
{
3246+
// Compare to classes we know we can use
3247+
if (env->IsInstanceOf(t_param, t_class_String) == JNI_TRUE)
3248+
{
3249+
char *t_cstring;
3250+
t_error = java_to__cstring(env, t_param, t_cstring);
3251+
if (t_error == kLCErrorNone)
3252+
{
3253+
t_error = (LCError)MCVariableStore(t_argv[i], kMCOptionAsCString, &t_cstring);
3254+
free(t_cstring);
3255+
}
3256+
}
3257+
if (env->IsInstanceOf(t_param, t_class_Boolean) == JNI_TRUE)
3258+
{
3259+
bool t_boolean = (bool) env -> CallBooleanMethod(t_param,t_mid_Boolean_booleanValue);
3260+
t_error = (LCError)MCVariableStore(t_argv[i], kMCOptionAsBoolean, &t_boolean);
3261+
}
3262+
if (env->IsInstanceOf(t_param, t_class_Integer) == JNI_TRUE)
3263+
{
3264+
int t_integer = (int) env -> CallIntMethod(t_param,t_mid_Integer_integerValue);
3265+
t_error = (LCError)MCVariableStore(t_argv[i], kMCOptionAsInteger, &t_integer);
3266+
}
3267+
if (env->IsInstanceOf(t_param, t_class_Double) == JNI_TRUE)
3268+
{
3269+
double t_double = (double) env -> CallDoubleMethod(t_param,t_mid_Double_doubleValue);
3270+
t_error = (LCError)MCVariableStore(t_argv[i], kMCOptionAsReal, &t_double);
3271+
}
3272+
if (env->IsInstanceOf(t_param, t_class_ByteBuffer) == JNI_TRUE)
3273+
{
3274+
//jobject t_byte_array = env -> CallObjectMethod(t_param,t_mid_ByteBuffer_array);
3275+
//LCBytes t_bytes = java_to__cdata(env, t_byte_array);
3276+
//t_error = (LCError)MCVariableStore(t_argv[i], kMCOptionAsString, &t_bytes);
3277+
}
3278+
}
3279+
}
3280+
3281+
if (t_error == kLCErrorNone)
3282+
{
3283+
r_argv = t_argv;
3284+
r_argc = t_argc;
3285+
}
3286+
else
3287+
LCArgumentsDestroy(t_argv, t_argc);
3288+
3289+
return t_error;
3290+
}
3291+
3292+
static void java_lcapi_ObjectSend(JNIEnv *env, jlong object, jobject message, jobjectArray arguments)
31183293
{
31193294
LCError t_error;
31203295
t_error = kLCErrorNone;
@@ -3123,37 +3298,130 @@ static void java_lcapi_ObjectSend(JNIEnv *env, jlong object, jobject message, jo
31233298
t_message_cstring = nil;
31243299
if (t_error == kLCErrorNone)
31253300
t_error = java_to__cstring(env, message, t_message_cstring);
3126-
3127-
// TODO handle signature / arguments
3301+
3302+
MCVariableRef *t_argv;
3303+
uint32_t t_argc;
3304+
t_argv = nil;
3305+
t_argc = 0;
3306+
if (t_error == kLCErrorNone)
3307+
t_error = java_lcapi_LCCreateArguments(env, arguments, t_argv, t_argc);
31283308

31293309
if (t_error == kLCErrorNone)
3130-
t_error = LCObjectSend((LCObjectRef)object, t_message_cstring, "");
3310+
{
3311+
MCDispatchStatus t_status;
3312+
t_error = (LCError)s_interface -> object_dispatch((MCObjectRef)object, kMCDispatchTypeCommand, t_message_cstring, t_argv, t_argc, &t_status);
3313+
if (t_error == kLCErrorNone)
3314+
{
3315+
switch(t_status)
3316+
{
3317+
case kMCDispatchStatusError:
3318+
t_error = kLCErrorFailed;
3319+
break;
3320+
case kMCDispatchStatusExit:
3321+
t_error = kLCErrorExited;
3322+
break;
3323+
case kMCDispatchStatusAbort:
3324+
t_error = kLCErrorAborted;
3325+
break;
3326+
default:
3327+
break;
3328+
}
3329+
}
3330+
}
31313331

3332+
LCArgumentsDestroy(t_argv, t_argc);
3333+
31323334
free(t_message_cstring);
31333335

31343336
if (t_error != kLCErrorNone)
31353337
{
31363338
java_lcapi__throw(env, t_error);
31373339
return;
3138-
}
3340+
}
31393341
}
31403342

3141-
static void java_lcapi_ObjectPost(JNIEnv *env, jlong object, jobject message, jobject signature, jobject arguments)
3343+
struct java_lcapi_LCObjectPost_context
31423344
{
3143-
LCError t_error;
3144-
t_error = kLCErrorNone;
3345+
MCObjectRef object;
3346+
char *message;
3347+
MCVariableRef *argv;
3348+
uint32_t argc;
3349+
LCError result;
3350+
};
3351+
3352+
static void java_lcapi_ObjectPost_perform(void *p_context)
3353+
{
3354+
java_lcapi_LCObjectPost_context *context;
3355+
context = (java_lcapi_LCObjectPost_context *)p_context;
3356+
3357+
LCError t_error;
3358+
t_error = kLCErrorNone;
31453359

3360+
struct LCObjectPostV_event *t_event;
3361+
t_event = nil;
3362+
if (t_error == kLCErrorNone)
3363+
{
3364+
t_event = (LCObjectPostV_event *)calloc(1, sizeof(LCObjectPostV_event));
3365+
if (t_event == nil)
3366+
t_error = kLCErrorOutOfMemory;
3367+
}
3368+
3369+
if (t_error == kLCErrorNone)
3370+
t_error = (LCError)s_interface -> object_retain(context -> object);
3371+
3372+
if (t_error == kLCErrorNone)
3373+
{
3374+
t_event -> object = context -> object;
3375+
t_event -> message = context -> message;
3376+
t_event -> argv = context -> argv;
3377+
t_event -> argc = context -> argc;
3378+
t_error = (LCError)s_interface -> engine_run_on_main_thread((void *)LCObjectPostV_dispatch, t_event, kMCRunOnMainThreadPost | kMCRunOnMainThreadRequired | kMCRunOnMainThreadSafe | kMCRunOnMainThreadDeferred);
3379+
}
3380+
3381+
if (t_error != kLCErrorNone)
3382+
{
3383+
if (t_event -> object != nil)
3384+
s_interface -> object_release(t_event -> object);
3385+
free(t_event -> message);
3386+
LCArgumentsDestroy(context -> argv, context -> argc);
3387+
free(t_event);
3388+
}
3389+
3390+
context -> result = (LCError)t_error;
3391+
}
3392+
3393+
static void java_lcapi_ObjectPost(JNIEnv *env, jlong object, jobject message, jobjectArray arguments)
3394+
{
3395+
LCError t_error;
3396+
t_error = kLCErrorNone;
3397+
3398+
// The cstring will be given to the perform method.
31463399
char *t_message_cstring;
31473400
t_message_cstring = nil;
31483401
if (t_error == kLCErrorNone)
31493402
t_error = java_to__cstring(env, message, t_message_cstring);
3150-
3151-
// TODO handle signature / arguments
3152-
3403+
3404+
// Create the arguments array here to make sure we don't get JNI thread problems.
3405+
// (this could be called from any thread, and we want to avoid having to make
3406+
// globalref's to the arguments array). The arguments array will be freed
3407+
// by the perform method (to stop threading problems engine-side).
3408+
MCVariableRef *t_argv;
3409+
uint32_t t_argc;
3410+
t_argv = nil;
3411+
t_argc = 0;
31533412
if (t_error == kLCErrorNone)
3154-
t_error = LCObjectPost((LCObjectRef)object, t_message_cstring, "");
3413+
t_error = java_lcapi_LCCreateArguments(env, arguments, t_argv, t_argc);
31553414

3156-
free(t_message_cstring);
3415+
struct java_lcapi_LCObjectPost_context t_context;
3416+
t_context . object = (MCObjectRef)object;
3417+
t_context . message = t_message_cstring;
3418+
t_context . argv = t_argv;
3419+
t_context . argc = t_argc;
3420+
if (t_error == kLCErrorNone)
3421+
t_error = (LCError)s_interface -> engine_run_on_main_thread((void *)java_lcapi_ObjectPost_perform, &t_context, kMCRunOnMainThreadSend | kMCRunOnMainThreadOptional | kMCRunOnMainThreadUnsafe | kMCRunOnMainThreadImmediate);
3422+
3423+
if (t_error == kLCErrorNone)
3424+
t_error = t_context . result;
31573425

31583426
if (t_error != kLCErrorNone)
31593427
{

revtestexternal/revtestexternal.lcidl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,6 @@ tail command revTestExternalAndroidButtonDestroy
5454

5555
function revTestExternalRunActivity return c-string
5656

57-
command revTestExternalRunOnSystemThread
57+
command revTestExternalRunOnSystemThread
58+
59+
command revTestExternalObjectPostAndSend
707 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)