Adding callback for C++ (still has bug for return values); adding struct as method...
[iot2.git] / iotjava / iotrmi / C++ / sample / TestClass_Stub.hpp
index 1749a59f7c5dfb37087818ecc39e7ec80b65d1fe..39ede876717f7602007f60a292072d3bbbc79087 100644 (file)
@@ -1,7 +1,13 @@
+#ifndef _TESTCLASS_STUB_HPP__
+#define _TESTCLASS_STUB_HPP__
+
 #include <iostream>
+#include <thread>
 #include "../IoTRMICall.hpp"
 #include "../IoTRMIObject.hpp"
 #include "TestClassInterface.hpp"
+#include "CallBack_CBSkeleton.hpp"
+#include "StructC.hpp"
 
 using namespace std;
 
@@ -21,9 +27,11 @@ class TestClass_Stub : public TestClassInterface {
                void                            registerCallback(CallBackInterface* _cb);
                void                            registerCallback(vector<CallBackInterface*>_cb);
                int                                     callBack();
-               void                            init_CallBack();
+               void                            handleStruct(vector<data> vecData);
+               void                            ____init_CallBack();    // thread
+               void                            ____registerCallBack(); // tell the other side that we are ready
 
-               const static int        size = 9;
+               const static int        size = 12;
                const static string methodSignatures[size];
 
        private:                
@@ -35,12 +43,16 @@ class TestClass_Stub : public TestClassInterface {
                IoTRMIObject                            *rmiObj;
                string                                          address;
                vector<int>                                     ports;
-               map<int,CallBackInterface*> mapCBObj;
+               vector<CallBackInterface*>      vecCBObj;
 
                int             objectId = 0;   // Default value is 0
+               static int      objIdCnt;
 };
 
 
+int TestClass_Stub::objIdCnt = 0;
+
+
 const string TestClass_Stub::methodSignatures[TestClass_Stub::size] = {
        "voidsetA(int)",
        "voidsetB(float)",
@@ -51,7 +63,10 @@ const string TestClass_Stub::methodSignatures[TestClass_Stub::size] = {
        "intsetACAndGetA(string,int)",
        "intcallBack()",
        "voidregisterCallBack(CallBackInterface)",
-       "voidregisterCallBack(CallBackInterface[])"
+       "voidregisterCallBack(CallBackInterface[])",
+       "registercallback",
+       "handleStruct(StructJ[])",
+       "structsize"
 };
 
 
@@ -67,6 +82,13 @@ TestClass_Stub::TestClass_Stub(int _port, const char* _address, int _rev, bool*
        address = _address;
        rmiCall = new IoTRMICall(_port, _address, _rev, _bResult, methodSignatures, size);
        ports = _ports;
+       // Start thread
+       cout << "Reached here 1!" << endl;
+//     thread th1 (&TestClass_Stub::____init_CallBack, this);
+//     th1.detach();
+       //th1.join();
+       cout << "Reached here 2!" << endl;
+//     ____registerCallBack();
 }
 
 
@@ -76,21 +98,66 @@ TestClass_Stub::~TestClass_Stub() {
                delete rmiCall;
                rmiCall = NULL;
        }
+       if (rmiObj != NULL) {
+               delete rmiObj;
+               rmiObj = NULL;
+       }
+       for(CallBackInterface* cb : vecCBObj) {
+               delete cb;
+               cb = NULL;
+       }
 }
 
 
 // Callback handler thread
-void TestClass_Stub::init_CallBack() {
+void TestClass_Stub::____init_CallBack() {
 
        bool bResult = false;
+       cout << "Reach here init!" << endl;
        rmiObj = new IoTRMIObject(ports[0], &bResult, CallBack_CBSkeleton::methodSignatures, CallBack_CBSkeleton::size);
+       cout << "Reach here init 2!" << endl;
        while (true) {
                char* method = rmiObj->getMethodBytes();
-               
+               cout << "Get method bytes here: " << endl;
+               IoTRMIUtil::printBytes(method, rmiObj->getMethodBytesLen(), false);
+               int objId = IoTRMIObject::getObjectId(method);
+               if (objId < vecCBObj.size()) {  // Check if still within range
+                       CallBack_CBSkeleton* skel = 
+                               dynamic_cast<CallBack_CBSkeleton*> (vecCBObj.at(objId));
+                       cout << "Dynamic cast done!" << endl;
+                       //rmiObj->setMethodBytes(method);
+                       string type = "";
+                       cout << "About to execute invoke method!" << endl;
+                       void* retObj = skel->invokeMethod(rmiObj, &type);
+                       cout << "Executed invoke method!" << endl;
+                       if (type != "void") {
+                               rmiObj->sendReturnObj(retObj, type);
+                               cout << "Sent return object!" << endl;
+                       }
+               } else {
+                       string error = "TestClass_Stub: Illegal object Id: " + to_string(objId);
+                       throw error;
+               }
        }
 }
 
 
+// Notify that callback thread is ready
+void TestClass_Stub::____registerCallBack() {
+
+       int numParam = 3;
+       string sign = "registercallback";
+       string retType = "void";
+       string paramCls[] = { "int", "string", "int" };
+       int rev = 0;
+       void* paramObj[] = { &ports[0], &address, &rev };
+       void* retObj = NULL;
+       cout << "Get here! 1" << endl;
+       rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
+       cout << "Get here! 2" << endl;
+}
+
+
 void TestClass_Stub::setA(int _int) {
 
        int numParam = 1;
@@ -192,7 +259,19 @@ void TestClass_Stub::registerCallback(CallBackInterface* _cb) {
 
 void TestClass_Stub::registerCallback(vector<CallBackInterface*> _cb) {
 
-       //Should implement the callback here for multiple callback objects
+       for (CallBackInterface* cb: _cb) {
+               CallBack_CBSkeleton* skel = new CallBack_CBSkeleton(cb, objIdCnt++);
+               vecCBObj.push_back(skel);
+       }
+
+       int numParam = 1;
+       string sign = "voidregisterCallBack(CallBackInterface[])";
+       string retType = "void";
+       string paramCls[] = { "int" };
+       int param1 = _cb.size();
+       void* paramObj[] = { &param1 };
+       void* retObj = NULL;
+       rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
 }
 
 
@@ -209,3 +288,36 @@ int TestClass_Stub::callBack() {
        return retVal;
 }
 
+
+void TestClass_Stub::handleStruct(vector<data> vecData) {
+
+       int numParam = 1;
+       string sign = "structsize";
+       string retType = "void";
+       string paramCls[] = { "int" };
+       int structsize = vecData.size();
+       void* paramObj[] = { &structsize };
+       void* retObj = NULL;
+       rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
+
+       int numParam2 = 3*vecData.size();
+       string sign2 = "handleStruct(StructJ[])";
+       string retType2 = "void";
+       string paramCls2[numParam2];
+       void* paramObj2[numParam2];
+       int pos = 0;
+       for(int i = 0; i < vecData.size(); i++) {
+               paramCls2[pos] = "string";
+               paramObj2[pos] = &vecData[i].name; pos++;
+               paramCls2[pos] = "float";
+               paramObj2[pos] = &vecData[i].value; pos++;
+               paramCls2[pos] = "int";
+               paramObj2[pos] = &vecData[i].year; pos++;
+       }
+       void* retObj2 = NULL;
+       cout << "In handle struct 3!" << endl;
+       rmiCall->remoteCall(objectId, sign2, retType2, paramCls2, paramObj2, numParam2, retObj2);
+}
+
+
+#endif