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