1 // CommonTestApp.cpp
2
3 #include <stdio.h>
4 #include <cstring>
5
6 #include <OS.h>
7
8 #include "CommonTestApp.h"
9
10 // constructor
CommonTestApp(const char * signature)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
CommonTestApp(const char * signature,status_t * result)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
~CommonTestApp()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
ArgvReceived(int32 argc,char ** argv)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
MessageReceived(BMessage * message)64 CommonTestApp::MessageReceived(BMessage *message)
65 {
66 if (fMessageHandler)
67 fMessageHandler->MessageReceived(message);
68 BApplication::MessageReceived(message);
69 }
70
71 // QuitRequested
72 bool
QuitRequested()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
ReadyToRun()86 CommonTestApp::ReadyToRun()
87 {
88 report("BApplication::ReadyToRun()\n");
89 }
90
91 // Run
92 thread_id
Run()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
SetQuittingPolicy(bool onSecondTry)102 CommonTestApp::SetQuittingPolicy(bool onSecondTry)
103 {
104 fQuitOnSecondTry = onSecondTry;
105 }
106
107 // SetReportDestruction
108 void
SetReportDestruction(bool reportDestruction)109 CommonTestApp::SetReportDestruction(bool reportDestruction)
110 {
111 fReportDestruction = reportDestruction;
112 }
113
114 // RunEventThread
115 status_t
RunEventThread(bigtime_t delay,int32 count,EventHandler * handler)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
SetMessageHandler(BHandler * handler)140 CommonTestApp::SetMessageHandler(BHandler *handler)
141 {
142 delete fMessageHandler;
143 fMessageHandler = handler;
144 }
145
146 // _EventThreadEntry
147 int32
_EventThreadEntry(void * data)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
_EventLoop()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
init_connection()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
report(const char * format,...)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
vreport(const char * format,va_list args)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