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