1// CommonTestApp.cpp 2 3#include <stdio.h> 4#include <cstring> 5 6#include <OS.h> 7 8#include "CommonTestApp.h" 9 10// constructor 11CommonTestApp::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 24CommonTestApp::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 37CommonTestApp::~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 50void 51CommonTestApp::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 63void 64CommonTestApp::MessageReceived(BMessage *message) 65{ 66 if (fMessageHandler) 67 fMessageHandler->MessageReceived(message); 68 BApplication::MessageReceived(message); 69} 70 71// QuitRequested 72bool 73CommonTestApp::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 85void 86CommonTestApp::ReadyToRun() 87{ 88 report("BApplication::ReadyToRun()\n"); 89} 90 91// Run 92thread_id 93CommonTestApp::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 101void 102CommonTestApp::SetQuittingPolicy(bool onSecondTry) 103{ 104 fQuitOnSecondTry = onSecondTry; 105} 106 107// SetReportDestruction 108void 109CommonTestApp::SetReportDestruction(bool reportDestruction) 110{ 111 fReportDestruction = reportDestruction; 112} 113 114// RunEventThread 115status_t 116CommonTestApp::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 139void 140CommonTestApp::SetMessageHandler(BHandler *handler) 141{ 142 delete fMessageHandler; 143 fMessageHandler = handler; 144} 145 146// _EventThreadEntry 147int32 148CommonTestApp::_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 157int32 158CommonTestApp::_EventLoop() 159{ 160 for (; fEventCount > 0; fEventCount--) { 161 snooze(fEventDelay); 162 if (fEventHandler) 163 fEventHandler->HandleEvent(this); 164 } 165 return 0; 166} 167 168static const char *kAppRunnerTeamPort = "app runner team port"; 169static bool connectionEstablished = false; 170static port_id outputPort = -1; 171 172// init_connection 173status_t 174init_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 200void 201report(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 213void 214vreport(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