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