#include <stdio.h>
#include <cstring>
#include <OS.h>
#include "CommonTestApp.h"
CommonTestApp::CommonTestApp(const char *signature)
: BApplication(signature),
fQuitOnSecondTry(false),
fEventThread(-1),
fEventDelay(0),
fEventCount(0),
fEventHandler(NULL),
fMessageHandler(NULL),
fReportDestruction(false)
{
}
CommonTestApp::CommonTestApp(const char *signature, status_t *result)
: BApplication(signature, result),
fQuitOnSecondTry(false),
fEventThread(-1),
fEventDelay(0),
fEventCount(0),
fEventHandler(NULL),
fMessageHandler(NULL),
fReportDestruction(false)
{
}
CommonTestApp::~CommonTestApp()
{
if (fEventThread >= 0) {
int32 result;
wait_for_thread(fEventThread, &result);
}
if (fReportDestruction)
report("BApplication::~BApplication()\n");
delete fEventHandler;
delete fMessageHandler;
}
void
CommonTestApp::ArgvReceived(int32 argc, char **argv)
{
report("BApplication::ArgvReceived()\n");
if (argc > 1) {
report("args:");
for (int32 i = 1; i < argc; i++)
report(" %s", argv[i]);
report("\n");
}
}
void
CommonTestApp::MessageReceived(BMessage *message)
{
if (fMessageHandler)
fMessageHandler->MessageReceived(message);
BApplication::MessageReceived(message);
}
bool
CommonTestApp::QuitRequested()
{
report("BApplication::QuitRequested()\n");
static bool firstTry = true;
if (firstTry && fQuitOnSecondTry) {
firstTry = false;
return false;
}
return BApplication::QuitRequested();
}
void
CommonTestApp::ReadyToRun()
{
report("BApplication::ReadyToRun()\n");
}
thread_id
CommonTestApp::Run()
{
thread_id result = BApplication::Run();
report("BApplication::Run() done: %d\n", (result == find_thread(NULL)));
return result;
}
void
CommonTestApp::SetQuittingPolicy(bool onSecondTry)
{
fQuitOnSecondTry = onSecondTry;
}
void
CommonTestApp::SetReportDestruction(bool reportDestruction)
{
fReportDestruction = reportDestruction;
}
status_t
CommonTestApp::RunEventThread(bigtime_t delay, int32 count,
EventHandler *handler)
{
status_t error = B_OK;
fEventDelay = delay;
fEventCount = count;
fEventHandler = handler;
fEventThread = spawn_thread(&_EventThreadEntry, "event thread",
B_NORMAL_PRIORITY, this);
if (fEventThread < 0)
error = fEventThread;
if (error == B_OK)
error = resume_thread(fEventThread);
if (error != B_OK && fEventThread >= 0) {
kill_thread(fEventThread);
fEventThread = -1;
}
return error;
}
void
CommonTestApp::SetMessageHandler(BHandler *handler)
{
delete fMessageHandler;
fMessageHandler = handler;
}
int32
CommonTestApp::_EventThreadEntry(void *data)
{
int32 result = 0;
if (CommonTestApp *app = (CommonTestApp*)data)
result = app->_EventLoop();
return result;
}
int32
CommonTestApp::_EventLoop()
{
for (; fEventCount > 0; fEventCount--) {
snooze(fEventDelay);
if (fEventHandler)
fEventHandler->HandleEvent(this);
}
return 0;
}
static const char *kAppRunnerTeamPort = "app runner team port";
static bool connectionEstablished = false;
static port_id outputPort = -1;
status_t
init_connection()
{
status_t error = B_OK;
outputPort = create_port(10, "common test app port");
if (outputPort < 0)
error = outputPort;
port_id port = -1;
if (error == B_OK) {
port = find_port(kAppRunnerTeamPort);
if (port < 0)
error = port;
}
if (error == B_OK) {
ssize_t written = write_port(port, outputPort, &be_app_messenger,
sizeof(BMessenger));
if (written < 0)
error = written;
}
connectionEstablished = (error == B_OK);
return error;
}
void
report(const char *format,...)
{
va_list args;
va_start(args, format);
if (connectionEstablished)
vreport(format, args);
else
vprintf(format, args);
va_end(args);
}
void
vreport(const char *format, va_list args)
{
char buffer[10240];
vsprintf(buffer, format, args);
int32 length = strlen(buffer);
write_port(outputPort, 0, buffer, length);
}