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