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