@@ -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 {
0 commit comments