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

Commit eb8e2ce

Browse files
committed
[[ AndroidListeners ]] Add Interface Proxy call type for binding string
Add a new java binding string variant - InterfaceProxy. When this type of binding string is used, the Android LCBInvocationHandler class is used to create a proxy for the specified listener interface.
1 parent 7ba7aac commit eb8e2ce

File tree

4 files changed

+72
-2
lines changed

4 files changed

+72
-2
lines changed

libfoundation/src/foundation-java-private.cpp

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ static bool __MCJavaCallNeedsClassInstance(MCJavaCallType p_type)
128128
{
129129
case MCJavaCallTypeStatic:
130130
case MCJavaCallTypeConstructor:
131+
case MCJavaCallTypeInterfaceProxy:
131132
case MCJavaCallTypeStaticGetter:
132133
case MCJavaCallTypeStaticSetter:
133134
return false;
@@ -150,10 +151,14 @@ static bool __RemoveSurroundingParentheses(MCStringRef p_in, MCStringRef& r_out)
150151

151152
bool MCJavaPrivateCheckSignature(MCTypeInfoRef p_signature, MCStringRef p_args, MCStringRef p_return, int p_call_type)
152153
{
154+
MCJavaCallType t_call_type = static_cast<MCJavaCallType>(p_call_type);
155+
if (t_call_type == MCJavaCallTypeInterfaceProxy)
156+
return true;
157+
153158
uindex_t t_param_count = MCHandlerTypeInfoGetParameterCount(p_signature);
154159

155160
uindex_t t_first_param = 0;
156-
if (__MCJavaCallNeedsClassInstance(static_cast<MCJavaCallType>(p_call_type)))
161+
if (__MCJavaCallNeedsClassInstance(t_call_type))
157162
{
158163
t_first_param = 1;
159164
}
@@ -183,6 +188,7 @@ bool MCJavaPrivateCheckSignature(MCTypeInfoRef p_signature, MCStringRef p_args,
183188
switch (p_call_type)
184189
{
185190
case MCJavaCallTypeConstructor:
191+
case MCJavaCallTypeInterfaceProxy:
186192
return __MCTypeInfoConformsToJavaType(t_return_type, kMCJavaTypeObject);
187193
case MCJavaCallTypeSetter:
188194
case MCJavaCallTypeStaticSetter:
@@ -1198,6 +1204,46 @@ static jclass MCJavaPrivateFindClass(MCNameRef p_class_name)
11981204
return s_env->FindClass(*t_class_cstring);
11991205
}
12001206

1207+
bool MCJavaCreateInterfaceProxy(MCNameRef p_class_name, MCTypeInfoRef p_signature, void *p_method_id, void *r_result, void **p_args, uindex_t p_arg_count)
1208+
{
1209+
if (MCHandlerTypeInfoGetParameterCount(p_signature) != 1)
1210+
return false;
1211+
1212+
MCValueRef t_handlers = *(static_cast<MCValueRef *>(p_args[0]));
1213+
if (MCValueGetTypeCode(t_handlers) == kMCValueTypeCodeArray)
1214+
{
1215+
// Array of handlers for interface proxy
1216+
}
1217+
else if (MCValueGetTypeCode(t_handlers) == kMCValueTypeCodeHandler)
1218+
{
1219+
// Single handler for listener interface
1220+
}
1221+
else
1222+
{
1223+
return false;
1224+
}
1225+
1226+
jclass t_inv_handler_class =
1227+
MCJavaPrivateFindClass(MCNAME("com.runrev.android.LCBInvocationHandler"));
1228+
1229+
jmethodID t_method = static_cast<jmethodID>(p_method_id);
1230+
1231+
jclass t_interface = MCJavaPrivateFindClass(p_class_name);
1232+
1233+
jlong t_handler = reinterpret_cast<jlong>(MCValueRetain(t_handlers));
1234+
1235+
jobject t_proxy = s_env->CallStaticObjectMethod(t_inv_handler_class,
1236+
t_method,
1237+
t_interface,
1238+
t_handler);
1239+
1240+
MCJavaObjectRef t_result_value;
1241+
if (!MCJavaObjectCreateNullableGlobalRef(t_proxy, t_result_value))
1242+
return false;
1243+
*(static_cast<MCJavaObjectRef *>(r_result)) = t_result_value;
1244+
return true;
1245+
}
1246+
12011247
bool MCJavaPrivateCallJNIMethod(MCNameRef p_class_name, void *p_method_id, int p_call_type, MCTypeInfoRef p_signature, void *r_return, void **p_args, uindex_t p_arg_count)
12021248
{
12031249
if (p_method_id == nullptr)
@@ -1210,11 +1256,20 @@ bool MCJavaPrivateCallJNIMethod(MCNameRef p_class_name, void *p_method_id, int p
12101256
return false;
12111257

12121258
jvalue *t_params = nullptr;
1213-
if (!__JavaJNIGetParams(p_args, p_signature, t_params))
1259+
if (p_call_type != MCJavaCallTypeInterfaceProxy &&
1260+
!__JavaJNIGetParams(p_args, p_signature, t_params))
12141261
return false;
12151262

12161263
switch (p_call_type)
12171264
{
1265+
case MCJavaCallTypeInterfaceProxy:
1266+
MCAssert(t_return_type == kMCJavaTypeObject);
1267+
if (!MCJavaCreateInterfaceProxy(p_class_name, p_signature,
1268+
p_method_id, r_return,
1269+
p_args, p_arg_count))
1270+
return false;
1271+
break;
1272+
12181273
// JavaJNI...Result functions only return false due to memory
12191274
// allocation failures. If they succeed, fall through the switch
12201275
// statement and check the JNIEnv for exceptions.
@@ -1469,6 +1524,16 @@ void* MCJavaPrivateGetMethodId(MCNameRef p_class_name, MCStringRef p_method_name
14691524
t_id = s_env->GetMethodID(t_java_class, "<init>", *t_signature_cstring);
14701525
break;
14711526
}
1527+
case MCJavaCallTypeInterfaceProxy:
1528+
{
1529+
jclass t_inv_handler_class =
1530+
MCJavaPrivateFindClass(MCNAME("com.runrev.android.LCBInvocationHandler"));
1531+
1532+
t_id = s_env->GetStaticMethodID(t_inv_handler_class,
1533+
"getProxy",
1534+
"(Ljava/lang/Class;J)Ljava/lang/Object;");
1535+
break;
1536+
}
14721537
case MCJavaCallTypeGetter:
14731538
t_id = s_env -> GetFieldID(t_java_class, *t_method_cstring, *t_return_cstring);
14741539
break;

libfoundation/src/foundation-java-private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ enum MCJavaCallType {
99
MCJavaCallTypeStatic,
1010
MCJavaCallTypeNonVirtual,
1111
MCJavaCallTypeConstructor,
12+
MCJavaCallTypeInterfaceProxy,
1213
MCJavaCallTypeGetter,
1314
MCJavaCallTypeSetter,
1415
MCJavaCallTypeStaticGetter,

libscript/src/script-instance.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,9 @@ static MCJavaCallType __MCScriptGetJavaCallType(MCStringRef p_class, MCStringRef
610610
if (MCStringIsEqualToCString(p_function, "new", kMCStringOptionCompareExact))
611611
return MCJavaCallTypeConstructor;
612612

613+
if (MCStringIsEqualToCString(p_function, "interface", kMCStringOptionCompareExact))
614+
return MCJavaCallTypeInterfaceProxy;
615+
613616
bool t_is_static =
614617
MCStringIsEqualToCString(p_calling, "static", kMCStringOptionCompareCaseless);
615618

libscript/src/script-private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ enum MCJavaCallType {
329329
MCJavaCallTypeStatic,
330330
MCJavaCallTypeNonVirtual,
331331
MCJavaCallTypeConstructor,
332+
MCJavaCallTypeInterfaceProxy,
332333
MCJavaCallTypeGetter,
333334
MCJavaCallTypeSetter,
334335
MCJavaCallTypeStaticGetter,

0 commit comments

Comments
 (0)