xref: /haiku/src/tests/kits/app/common/CommonTestApp.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
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