1*cb19e5d2SIngo Weinhold // CommonTestApp.cpp 2*cb19e5d2SIngo Weinhold 3*cb19e5d2SIngo Weinhold #include <stdio.h> 4*cb19e5d2SIngo Weinhold 5*cb19e5d2SIngo Weinhold #include <OS.h> 6*cb19e5d2SIngo Weinhold 7*cb19e5d2SIngo Weinhold #include "CommonTestApp.h" 8*cb19e5d2SIngo Weinhold 9*cb19e5d2SIngo Weinhold // constructor 10*cb19e5d2SIngo Weinhold CommonTestApp::CommonTestApp(const char *signature) 11*cb19e5d2SIngo Weinhold : BApplication(signature), 12*cb19e5d2SIngo Weinhold fQuitOnSecondTry(false), 13*cb19e5d2SIngo Weinhold fEventThread(-1), 14*cb19e5d2SIngo Weinhold fEventDelay(0), 15*cb19e5d2SIngo Weinhold fEventCount(0), 16*cb19e5d2SIngo Weinhold fEventHandler(NULL), 17*cb19e5d2SIngo Weinhold fMessageHandler(NULL), 18*cb19e5d2SIngo Weinhold fReportDestruction(false) 19*cb19e5d2SIngo Weinhold { 20*cb19e5d2SIngo Weinhold } 21*cb19e5d2SIngo Weinhold 22*cb19e5d2SIngo Weinhold // constructor 23*cb19e5d2SIngo Weinhold CommonTestApp::CommonTestApp(const char *signature, status_t *result) 24*cb19e5d2SIngo Weinhold : BApplication(signature, result) 25*cb19e5d2SIngo Weinhold { 26*cb19e5d2SIngo Weinhold } 27*cb19e5d2SIngo Weinhold 28*cb19e5d2SIngo Weinhold // destructor 29*cb19e5d2SIngo Weinhold CommonTestApp::~CommonTestApp() 30*cb19e5d2SIngo Weinhold { 31*cb19e5d2SIngo Weinhold if (fEventThread >= 0) { 32*cb19e5d2SIngo Weinhold int32 result; 33*cb19e5d2SIngo Weinhold wait_for_thread(fEventThread, &result); 34*cb19e5d2SIngo Weinhold } 35*cb19e5d2SIngo Weinhold if (fReportDestruction) 36*cb19e5d2SIngo Weinhold report("BApplication::~BApplication()\n"); 37*cb19e5d2SIngo Weinhold delete fEventHandler; 38*cb19e5d2SIngo Weinhold delete fMessageHandler; 39*cb19e5d2SIngo Weinhold } 40*cb19e5d2SIngo Weinhold 41*cb19e5d2SIngo Weinhold // ArgvReceived 42*cb19e5d2SIngo Weinhold void 43*cb19e5d2SIngo Weinhold CommonTestApp::ArgvReceived(int32 argc, char **argv) 44*cb19e5d2SIngo Weinhold { 45*cb19e5d2SIngo Weinhold report("BApplication::ArgvReceived()\n"); 46*cb19e5d2SIngo Weinhold if (argc > 1) { 47*cb19e5d2SIngo Weinhold report("args:"); 48*cb19e5d2SIngo Weinhold for (int32 i = 1; i < argc; i++) 49*cb19e5d2SIngo Weinhold report(" %s", argv[i]); 50*cb19e5d2SIngo Weinhold report("\n"); 51*cb19e5d2SIngo Weinhold } 52*cb19e5d2SIngo Weinhold } 53*cb19e5d2SIngo Weinhold 54*cb19e5d2SIngo Weinhold // MessageReceived 55*cb19e5d2SIngo Weinhold void 56*cb19e5d2SIngo Weinhold CommonTestApp::MessageReceived(BMessage *message) 57*cb19e5d2SIngo Weinhold { 58*cb19e5d2SIngo Weinhold if (fMessageHandler) 59*cb19e5d2SIngo Weinhold fMessageHandler->MessageReceived(message); 60*cb19e5d2SIngo Weinhold BApplication::MessageReceived(message); 61*cb19e5d2SIngo Weinhold } 62*cb19e5d2SIngo Weinhold 63*cb19e5d2SIngo Weinhold // QuitRequested 64*cb19e5d2SIngo Weinhold bool 65*cb19e5d2SIngo Weinhold CommonTestApp::QuitRequested() 66*cb19e5d2SIngo Weinhold { 67*cb19e5d2SIngo Weinhold report("BApplication::QuitRequested()\n"); 68*cb19e5d2SIngo Weinhold static bool firstTry = true; 69*cb19e5d2SIngo Weinhold if (firstTry && fQuitOnSecondTry) { 70*cb19e5d2SIngo Weinhold firstTry = false; 71*cb19e5d2SIngo Weinhold return false; 72*cb19e5d2SIngo Weinhold } 73*cb19e5d2SIngo Weinhold return BApplication::QuitRequested(); 74*cb19e5d2SIngo Weinhold } 75*cb19e5d2SIngo Weinhold 76*cb19e5d2SIngo Weinhold // ReadyToRun 77*cb19e5d2SIngo Weinhold void 78*cb19e5d2SIngo Weinhold CommonTestApp::ReadyToRun() 79*cb19e5d2SIngo Weinhold { 80*cb19e5d2SIngo Weinhold report("BApplication::ReadyToRun()\n"); 81*cb19e5d2SIngo Weinhold } 82*cb19e5d2SIngo Weinhold 83*cb19e5d2SIngo Weinhold // Run 84*cb19e5d2SIngo Weinhold thread_id 85*cb19e5d2SIngo Weinhold CommonTestApp::Run() 86*cb19e5d2SIngo Weinhold { 87*cb19e5d2SIngo Weinhold thread_id result = BApplication::Run(); 88*cb19e5d2SIngo Weinhold report("BApplication::Run() done: %d\n", (result == find_thread(NULL))); 89*cb19e5d2SIngo Weinhold return result; 90*cb19e5d2SIngo Weinhold } 91*cb19e5d2SIngo Weinhold 92*cb19e5d2SIngo Weinhold // SetQuittingPolicy 93*cb19e5d2SIngo Weinhold void 94*cb19e5d2SIngo Weinhold CommonTestApp::SetQuittingPolicy(bool onSecondTry) 95*cb19e5d2SIngo Weinhold { 96*cb19e5d2SIngo Weinhold fQuitOnSecondTry = onSecondTry; 97*cb19e5d2SIngo Weinhold } 98*cb19e5d2SIngo Weinhold 99*cb19e5d2SIngo Weinhold // SetReportDestruction 100*cb19e5d2SIngo Weinhold void 101*cb19e5d2SIngo Weinhold CommonTestApp::SetReportDestruction(bool reportDestruction) 102*cb19e5d2SIngo Weinhold { 103*cb19e5d2SIngo Weinhold fReportDestruction = reportDestruction; 104*cb19e5d2SIngo Weinhold } 105*cb19e5d2SIngo Weinhold 106*cb19e5d2SIngo Weinhold // RunEventThread 107*cb19e5d2SIngo Weinhold status_t 108*cb19e5d2SIngo Weinhold CommonTestApp::RunEventThread(bigtime_t delay, int32 count, 109*cb19e5d2SIngo Weinhold EventHandler *handler) 110*cb19e5d2SIngo Weinhold { 111*cb19e5d2SIngo Weinhold status_t error = B_OK; 112*cb19e5d2SIngo Weinhold fEventDelay = delay; 113*cb19e5d2SIngo Weinhold fEventCount = count; 114*cb19e5d2SIngo Weinhold fEventHandler = handler; 115*cb19e5d2SIngo Weinhold // spawn the thread 116*cb19e5d2SIngo Weinhold fEventThread = spawn_thread(&_EventThreadEntry, "event thread", 117*cb19e5d2SIngo Weinhold B_NORMAL_PRIORITY, this); 118*cb19e5d2SIngo Weinhold if (fEventThread < 0) 119*cb19e5d2SIngo Weinhold error = fEventThread; 120*cb19e5d2SIngo Weinhold if (error == B_OK) 121*cb19e5d2SIngo Weinhold error = resume_thread(fEventThread); 122*cb19e5d2SIngo Weinhold // cleanup on error 123*cb19e5d2SIngo Weinhold if (error != B_OK && fEventThread >= 0) { 124*cb19e5d2SIngo Weinhold kill_thread(fEventThread); 125*cb19e5d2SIngo Weinhold fEventThread = -1; 126*cb19e5d2SIngo Weinhold } 127*cb19e5d2SIngo Weinhold return error; 128*cb19e5d2SIngo Weinhold } 129*cb19e5d2SIngo Weinhold 130*cb19e5d2SIngo Weinhold // SetMessageHandler 131*cb19e5d2SIngo Weinhold void 132*cb19e5d2SIngo Weinhold CommonTestApp::SetMessageHandler(BHandler *handler) 133*cb19e5d2SIngo Weinhold { 134*cb19e5d2SIngo Weinhold delete fMessageHandler; 135*cb19e5d2SIngo Weinhold fMessageHandler = handler; 136*cb19e5d2SIngo Weinhold } 137*cb19e5d2SIngo Weinhold 138*cb19e5d2SIngo Weinhold // _EventThreadEntry 139*cb19e5d2SIngo Weinhold int32 140*cb19e5d2SIngo Weinhold CommonTestApp::_EventThreadEntry(void *data) 141*cb19e5d2SIngo Weinhold { 142*cb19e5d2SIngo Weinhold int32 result = 0; 143*cb19e5d2SIngo Weinhold if (CommonTestApp *app = (CommonTestApp*)data) 144*cb19e5d2SIngo Weinhold result = app->_EventLoop(); 145*cb19e5d2SIngo Weinhold return result; 146*cb19e5d2SIngo Weinhold } 147*cb19e5d2SIngo Weinhold 148*cb19e5d2SIngo Weinhold // _EventLoop 149*cb19e5d2SIngo Weinhold int32 150*cb19e5d2SIngo Weinhold CommonTestApp::_EventLoop() 151*cb19e5d2SIngo Weinhold { 152*cb19e5d2SIngo Weinhold for (; fEventCount > 0; fEventCount--) { 153*cb19e5d2SIngo Weinhold snooze(fEventDelay); 154*cb19e5d2SIngo Weinhold if (fEventHandler) 155*cb19e5d2SIngo Weinhold fEventHandler->HandleEvent(this); 156*cb19e5d2SIngo Weinhold } 157*cb19e5d2SIngo Weinhold return 0; 158*cb19e5d2SIngo Weinhold } 159*cb19e5d2SIngo Weinhold 160*cb19e5d2SIngo Weinhold static const char *kAppRunnerTeamPort = "app runner team port"; 161*cb19e5d2SIngo Weinhold static bool connectionEstablished = false; 162*cb19e5d2SIngo Weinhold static port_id outputPort = -1; 163*cb19e5d2SIngo Weinhold 164*cb19e5d2SIngo Weinhold // init_connection 165*cb19e5d2SIngo Weinhold status_t 166*cb19e5d2SIngo Weinhold init_connection() 167*cb19e5d2SIngo Weinhold { 168*cb19e5d2SIngo Weinhold status_t error = B_OK; 169*cb19e5d2SIngo Weinhold // create a port 170*cb19e5d2SIngo Weinhold outputPort = create_port(10, "common test app port"); 171*cb19e5d2SIngo Weinhold if (outputPort < 0) 172*cb19e5d2SIngo Weinhold error = outputPort; 173*cb19e5d2SIngo Weinhold // find the remote port 174*cb19e5d2SIngo Weinhold port_id port = -1; 175*cb19e5d2SIngo Weinhold if (error == B_OK) { 176*cb19e5d2SIngo Weinhold port = find_port(kAppRunnerTeamPort); 177*cb19e5d2SIngo Weinhold if (port < 0) 178*cb19e5d2SIngo Weinhold error = port; 179*cb19e5d2SIngo Weinhold } 180*cb19e5d2SIngo Weinhold // send the port ID 181*cb19e5d2SIngo Weinhold if (error == B_OK) { 182*cb19e5d2SIngo Weinhold ssize_t written = write_port(port, outputPort, &be_app_messenger, 183*cb19e5d2SIngo Weinhold sizeof(BMessenger)); 184*cb19e5d2SIngo Weinhold if (written < 0) 185*cb19e5d2SIngo Weinhold error = written; 186*cb19e5d2SIngo Weinhold } 187*cb19e5d2SIngo Weinhold connectionEstablished = (error == B_OK); 188*cb19e5d2SIngo Weinhold return error; 189*cb19e5d2SIngo Weinhold } 190*cb19e5d2SIngo Weinhold 191*cb19e5d2SIngo Weinhold // report 192*cb19e5d2SIngo Weinhold void 193*cb19e5d2SIngo Weinhold report(const char *format,...) 194*cb19e5d2SIngo Weinhold { 195*cb19e5d2SIngo Weinhold va_list args; 196*cb19e5d2SIngo Weinhold va_start(args, format); 197*cb19e5d2SIngo Weinhold if (connectionEstablished) 198*cb19e5d2SIngo Weinhold vreport(format, args); 199*cb19e5d2SIngo Weinhold else 200*cb19e5d2SIngo Weinhold vprintf(format, args); 201*cb19e5d2SIngo Weinhold va_end(args); 202*cb19e5d2SIngo Weinhold } 203*cb19e5d2SIngo Weinhold 204*cb19e5d2SIngo Weinhold // vreport 205*cb19e5d2SIngo Weinhold void 206*cb19e5d2SIngo Weinhold vreport(const char *format, va_list args) 207*cb19e5d2SIngo Weinhold { 208*cb19e5d2SIngo Weinhold char buffer[10240]; 209*cb19e5d2SIngo Weinhold vsprintf(buffer, format, args); 210*cb19e5d2SIngo Weinhold int32 length = strlen(buffer); 211*cb19e5d2SIngo Weinhold write_port(outputPort, 0, buffer, length); 212*cb19e5d2SIngo Weinhold } 213*cb19e5d2SIngo Weinhold 214