This is the C++ handler which will be called by clientSML when the event fires. Then from here we need to call back to Java to pass back the message.
| 582 | // This is the C++ handler which will be called by clientSML when the event fires. |
| 583 | // Then from here we need to call back to Java to pass back the message. |
| 584 | static void XMLEventHandler(sml::smlXMLEventId id, void* pUserData, sml::Agent* pAgent, sml::ClientXML* pXML) |
| 585 | { |
| 586 | // The user data is the class we declared above, where we store the Java data to use in the callback. |
| 587 | JavaCallbackData* pJavaData = (JavaCallbackData*)pUserData ; |
| 588 | |
| 589 | // Now try to call back to Java |
| 590 | JNIEnv* jenv = pJavaData->GetEnv() ; |
| 591 | |
| 592 | // We start from the Java object whose method we wish to call. |
| 593 | jobject jobj = pJavaData->m_HandlerObject ; |
| 594 | jclass cls = jenv->GetObjectClass(jobj) ; |
| 595 | |
| 596 | if (cls == 0) |
| 597 | { |
| 598 | printf("Failed to get Java class\n") ; |
| 599 | return ; |
| 600 | } |
| 601 | |
| 602 | // Look up the Java method we want to call. |
| 603 | // The method name is passed in by the user (and needs to match exactly, including case). |
| 604 | // The method should be owned by the m_HandlerObject that the user also passed in. |
| 605 | // Any slip here and you get a NoSuchMethod exception and my Java VM shuts down. |
| 606 | jmethodID mid = jenv->GetMethodID(cls, pJavaData->m_HandlerMethod.c_str(), "(ILjava/lang/Object;Lsml/Agent;Lsml/ClientXML;)V") ; |
| 607 | |
| 608 | if (mid == 0) |
| 609 | { |
| 610 | printf("Failed to get Java method\n") ; |
| 611 | return ; |
| 612 | } |
| 613 | |
| 614 | // Wrap our C++ ClientXML object with a SWIG sml/ClientXML Java object so we can |
| 615 | // pass it back to Java. |
| 616 | // OK, time to roll up our JNI sleeves and get dirty. We need to create a new Java object. |
| 617 | // Step one is getting the constructor for that class: <init> as the method name and void (V) |
| 618 | char const* kClassName = "sml/ClientXML" ; |
| 619 | jclass jsmlClass = jenv->FindClass(kClassName) ; |
| 620 | |
| 621 | if (!jsmlClass) |
| 622 | { |
| 623 | return ; |
| 624 | } |
| 625 | |
| 626 | // We want to grab the SWIG constructor which in Java is: |
| 627 | // protected ClientXML(long cPtr, boolean cMemoryOwn) { |
| 628 | // swigCMemOwn = cMemoryOwn; |
| 629 | // swigCPtr = cPtr; |
| 630 | // } |
| 631 | // J == long, Z == boolean so looking for constructor (long, boolean) |
| 632 | jmethodID cons = jenv->GetMethodID(jsmlClass, "<init>", "(JZ)V") ; |
| 633 | |
| 634 | if (!cons) |
| 635 | { |
| 636 | return ; |
| 637 | } |
| 638 | |
| 639 | // Call constructor with the address of the C++ object that is being wrapped |
| 640 | // by the SWIG sml/ClientXML object. To mimic the C++ semantics we'll create a new |
| 641 | // SWIG (Java) object which does not own pXML (achieved by passing "false" as second param). |