1/*
2 * Copyright (C) 2008-2009 Stephan A��mus <superstippi@gmx.de>
3 * All rights reserved. Distributed under the terms of the MIT license.
4 */
5
6#include <memory>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include <Application.h>
12#include <Screen.h>
13
14#include "DrawingModeToString.h"
15#include "TestWindow.h"
16
17// tests
18#include "HorizontalLineTest.h"
19#include "RandomLineTest.h"
20#include "StringTest.h"
21#include "VerticalLineTest.h"
22
23
24struct test_info {
25	const char*				name;
26	Test*					(*create)();
27};
28
29const test_info kTestInfos[] = {
30	{ "HorizontalLines",	HorizontalLineTest::CreateTest },
31	{ "RandomLines",		RandomLineTest::CreateTest },
32	{ "Strings",			StringTest::CreateTest },
33	{ "VerticalLines",		VerticalLineTest::CreateTest },
34	{ NULL, NULL }
35};
36
37
38class Benchmark : public BApplication {
39public:
40	Benchmark(Test* test, drawing_mode mode, bool clipping)
41		: BApplication("application/x-vnd.haiku-benchmark"),
42		  fTest(test),
43		  fTestWindow(NULL),
44		  fDrawingMode(mode),
45		  fUseClipping(clipping)
46	{
47	}
48
49	~Benchmark()
50	{
51		delete fTest;
52	}
53
54	virtual	void ReadyToRun()
55	{
56		uint32 width = 500;
57		uint32 height = 500;
58		BScreen screen;
59		BRect frame = screen.Frame();
60		frame.left = (frame.left + frame.right - width) / 2;
61		frame.top = (frame.top + frame.bottom - width) / 2;
62		frame.right = frame.left + width - 1;
63		frame.bottom = frame.top + height - 1;
64
65		fTestWindow = new TestWindow(frame, fTest, fDrawingMode,
66			fUseClipping, BMessenger(this));
67	}
68
69	virtual bool QuitRequested()
70	{
71		if (fTestWindow != NULL)
72			fTestWindow->SetAllowedToQuit(true);
73		return BApplication::QuitRequested();
74	}
75
76	virtual void MessageReceived(BMessage* message)
77	{
78		switch (message->what) {
79			case MSG_TEST_CANCELED:
80				printf("Test canceled early.\n");
81				// fall through
82			case MSG_TEST_FINISHED:
83				fTestWindow->Lock();
84				fTest->PrintResults(fTestWindow->View());
85				fTestWindow->Unlock();
86				PostMessage(B_QUIT_REQUESTED);
87				break;
88			default:
89				BApplication::MessageReceived(message);
90				break;
91		}
92	}
93
94private:
95	Test*			fTest;
96	TestWindow*		fTestWindow;
97	drawing_mode	fDrawingMode;
98	bool			fUseClipping;
99};
100
101
102static void
103print_test_list(bool error)
104{
105	FILE* out = (error ? stderr : stdout);
106
107	fprintf(out, "available tests:\n");
108
109	for (int32 i = 0; kTestInfos[i].name; i++)
110		fprintf(out, "  %s\n", kTestInfos[i].name);
111}
112
113
114int
115main(int argc, char** argv)
116{
117	// get test name
118	const char* testName;
119	if (argc < 2) {
120		fprintf(stderr, "Usage: %s <test name>\n", argv[0]);
121		print_test_list(true);
122		exit(1);
123	}
124	// skip program name
125	argc--;
126	argv++;
127
128	testName = argv[0];
129	bool clipping = false;
130	drawing_mode mode = B_OP_COPY;
131
132	while (argc > 0) {
133		drawing_mode possibleMode;
134		if (strcmp(argv[0], "--clipping") == 0 || strcmp(argv[0], "-c") == 0) {
135			clipping = true;
136		} else if (ToDrawingMode(argv[0], possibleMode)) {
137			mode = possibleMode;
138		}
139		argc--;
140		argv++;
141	}
142
143
144	// find and create the test
145	Test* test = NULL;
146	try {
147		for (int32 i = 0; kTestInfos[i].name; i++) {
148			if (strcmp(testName, kTestInfos[i].name) == 0) {
149				test = (kTestInfos[i].create)();
150				break;
151			}
152		}
153	} catch (std::bad_alloc) {
154		fprintf(stderr, "Insufficient memory to create the test. Sorry.\n");
155		exit(1);
156	}
157
158	if (test == NULL) {
159		fprintf(stderr, "Error: Invalid test name: \"%s\"\n", testName);
160		print_test_list(true);
161		exit(1);
162	}
163
164	Benchmark app(test, mode, clipping);
165	app.Run();
166	return 0;
167}
168