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