/** Open the server, if you supply a robot this will run in the robots attached, if you do not supply a robot then it will be open and you'll have to call runOnce yourself (this is only recommended for advanced users) @param robot the robot that this should be attached to and run in the sync task of or NULL not to run in any robot's task @param port the port to start up the service on @param password the password needed to use the service @param multipleClients if false only one client is allowed to connect, if false multiple clients are allowed to connect or just one @return true if the server could be started, false otherwise **/ AREXPORT bool ArNetServer::open(ArRobot *robot, unsigned int port, const char *password, bool multipleClients, const char *openOnIP) { ArSyncTask *rootTask = NULL; ArSyncTask *proc = NULL; std::string taskName; if (myOpened) { ArLog::log(ArLog::Terse, "ArNetServer already inited, cannot reinit"); return false; } myRobot = robot; myPort = port; myPassword = password; myMultipleClients = multipleClients; if (myServerSocket.open(myPort, ArSocket::TCP, openOnIP)) { myServerSocket.setLinger(0); myServerSocket.setNonBlock(); if (openOnIP != NULL) ArLog::log(ArLog::Normal, "ArNetServer opened on port %d on ip %s.", myPort, openOnIP); else ArLog::log(ArLog::Normal, "ArNetServer opened on port %d.", myPort); myOpened = true; } else { ArLog::log(ArLog::Terse, "ArNetServer failed to open: %s", myServerSocket.getErrorStr().c_str()); myOpened = false; return false; } // add ourselves to the robot if we aren't already there if (myRobot != NULL && (rootTask = myRobot->getSyncTaskRoot()) != NULL) { proc = rootTask->findNonRecursive(&myTaskCB); if (proc == NULL) { // toss in a netserver taskName = "Net Servers "; taskName += myPort; rootTask->addNewLeaf(taskName.c_str(), 60, &myTaskCB, NULL); } } return true; }
/** Finds a child of this node with the given functor @param functor the functor we are interested in finding @return The task, if found. If not found, NULL. */ AREXPORT ArSyncTask *ArSyncTask::findNonRecursive(ArFunctor *functor) { ArSyncTask *proc; std::multimap<int, ArSyncTask *>::iterator it; for (it = myMultiMap.begin(); it != myMultiMap.end(); ++it) { proc = (*it).second; if (proc->getFunctor() == functor) return proc; } return NULL; }
ArNetServer::~ArNetServer() { ArSyncTask *rootTask = NULL; ArSyncTask *proc = NULL; // get rid of us running on the robot task if (myRobot != NULL && (rootTask = myRobot->getSyncTaskRoot()) != NULL) { proc = rootTask->findNonRecursive(&myTaskCB); if (proc != NULL) delete proc; } close(); }
/** Finds a child of this node with the given name @param name The name of the child we are interested in finding @return The task, if found. If not found, NULL. */ AREXPORT ArSyncTask *ArSyncTask::findNonRecursive(const char * name) { ArSyncTask *proc; std::multimap<int, ArSyncTask *>::iterator it; for (it = myMultiMap.begin(); it != myMultiMap.end(); ++it) { proc = (*it).second; if (strcmp(proc->getName().c_str(), name) == 0) return proc; } return NULL; }
AREXPORT const char *ArSyncLoop::getThreadActivity(void) { if (myRunning) { ArSyncTask *syncTask; syncTask = myRobot->getSyncTaskRoot()->getRunning(); if (syncTask != NULL) return syncTask->getName().c_str(); else return "Unknown running"; } else return "Unknown"; }
/** Finds a node below (or at) this level in the tree with the given name @param name The name of the child we are interested in finding @return The task, if found. If not found, NULL. */ AREXPORT ArSyncTask *ArSyncTask::find(ArFunctor *functor) { ArSyncTask *proc; std::multimap<int, ArSyncTask *>::iterator it; if (myFunctor == functor) return this; for (it = myMultiMap.begin(); it != myMultiMap.end(); ++it) { proc = (*it).second; if (proc->find(functor) != NULL) return proc; } return NULL; }
/** Finds a node below (or at) this level in the tree with the given name @param name The name of the child we are interested in finding @return The task, if found. If not found, NULL. */ AREXPORT ArSyncTask *ArSyncTask::find(const char *name) { ArSyncTask *proc; std::multimap<int, ArSyncTask *>::iterator it; if (strcmp(myName.c_str(), name) == 0) return this; for (it = myMultiMap.begin(); it != myMultiMap.end(); ++it) { proc = (*it).second; if (proc->find(name) != NULL) return proc; } return NULL; }
int main() { ArSyncTask *task; UserTaskTest test; ArRobot robot; ArFunctorC<UserTaskTest> userTaskOne(&test, &UserTaskTest::userTaskOne); ArFunctorC<UserTaskTest> userTaskTwo(&test, &UserTaskTest::userTaskTwo); ArFunctorC<UserTaskTest> userTaskThree(&test, &UserTaskTest::userTaskThree); ArFunctorC<UserTaskTest> userTaskFour(&test, &UserTaskTest::userTaskFour); printf("Before tasks added:\n"); robot.logUserTasks(); printf("---------------------------------------------------------------\n"); // the order you add tasks doesn't matter, it goes off of the integer // you give the function call to add them // Caveat: if you give the function call the same number it goes off of order robot.addUserTask("procTwo", 20, &userTaskTwo); robot.addUserTask("procFour", 40, &userTaskFour, &test.myTaskFourState); robot.addUserTask("procThree", 30, &userTaskThree); robot.addUserTask("procOne", 10, &userTaskOne); printf("After tasks added:\n"); robot.logUserTasks(); printf("---------------------------------------------------------------\n"); printf("What happens when these are run:\n"); robot.loopOnce(); printf("---------------------------------------------------------------\n"); printf("After tasks removed by name:\n"); printf("---------------------------------------------------------------\n"); robot.remUserTask("procOne"); robot.remUserTask("procTwo"); robot.remUserTask("procThree"); robot.remUserTask("procFour"); robot.logUserTasks(); printf("\nAfter they are added again, procThree is found by name and set to SUSPEND and procFour is found by functor and set to FAILURE:\n"); printf("---------------------------------------------------------------\n"); printf("---------------------------------------------------------------\n"); robot.addUserTask("procTwo", 20, &userTaskTwo); robot.addUserTask("procFour", 40, &userTaskFour, &test.myTaskFourState); robot.addUserTask("procThree", 30, &userTaskThree); robot.addUserTask("procOne", 10, &userTaskOne); task = robot.findUserTask("procThree"); if (task != NULL) task->setState(ArTaskState::SUSPEND); task = robot.findUserTask(&userTaskFour); if (task != NULL) task->setState(ArTaskState::FAILURE); robot.logUserTasks(); task = robot.findUserTask(&userTaskFour); if (task != NULL) { printf("---------------------------------------------------------------\n"); printf("Did the real state on procFourState get set:\n"); printf("getState: %d realState: %d\n", task->getState(), test.myTaskFourState); } printf("---------------------------------------------------------------\n"); printf("What happens when these are run:\n"); robot.loopOnce(); printf("---------------------------------------------------------------\n"); printf("After tasks removed by functor:\n"); printf("---------------------------------------------------------------\n"); robot.remUserTask(&userTaskOne); robot.remUserTask(&userTaskTwo); robot.remUserTask(&userTaskThree); robot.remUserTask(&userTaskFour); robot.logUserTasks(); }