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