when to separate

closed account (zwA4jE8b)
Same code as before...

I feel as if I have too much packed into one file even though it works well.

When should I start to separate code?
I feel like all my structs could be in a separate header file (and pass hdc and colorref as a parameter for circle).

Any tips?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
//Michael Ervin - Windows Sine Wave

#include <Windows.h>
#include <math.h>
#include <string>
#include <sstream>

#define screen_width 800
#define screen_height 600
#define pi 3.14159
#define rad  (3.14159/180);

struct _points
{
	int _x;
	int _y;
};

struct _ycoords
{
	_points _one;
	_points _two;
} _yc;

COLORREF blue = RGB(0, 0, 255);
HDC hDC;
HWND hWnd;
std::string _amplitude, _frequency, _speed;

struct circle
{
	circle(){drawcircle();}
private:
	void drawcircle()
	{
		for(double c = 1; c < 360; c+=6)
		{SetPixel(hDC, _yc._one._x + std::cos(c)*5, _yc._one._y + sin(c)*5, blue);}
	}
};

double _freq = 50;
int _sTime = 10, _amp = 100;

const RECT rect = {0, 50, screen_width, screen_height};

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void calcwave();
void drawwave();
std::string convstr(const int& t);
void drawcirc();

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
	WNDCLASSEXA wc;

	ZeroMemory(&wc, sizeof(WNDCLASSEX));
	ZeroMemory(&_yc, sizeof(_yc));
	_yc._one._x = 600;
	_yc._two._x = 599;
	_yc._two._y = 300;

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WindowProc;
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hIcon = (HICON)LoadImageA(NULL, "C:\\Visual Studio 2010\\Icons\\Smiley.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
	wc.lpszClassName = "SineWave";

	RegisterClassExA(&wc);

	hWnd = CreateWindowExA(NULL,
                          "SineWave", "SineWave",
                          WS_SYSMENU,
                          0, 45,
                          screen_width, screen_height,
                          NULL, NULL,
                          hInstance,
                          NULL);

	ShowWindow(hWnd, nCmdShow);
	hDC = GetDC(hWnd);

	HPEN _Pen = CreatePen(PS_SOLID, 1, blue);
	SelectObject(hDC, _Pen);

	MSG msg;

	while(TRUE)
	{
		while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{DispatchMessage(&msg);}

		if(msg.message == WM_QUIT)
			break;

		calcwave();
	}
	return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
		case WM_DESTROY:
		{
			PostQuitMessage(0);
			return 0;
		} break;
		case WM_KEYDOWN:
		{
			switch (wParam)
			{
			case VK_NUMPAD4:
				_freq--;
				if(_freq < 1.0)
					_freq = 1.0;
				break;
			case VK_NUMPAD6:
				_freq++;
				break;
			case VK_NUMPAD8:
				_amp++;
				if(_amp > 200)
					_amp = 200;
				break;
			case VK_NUMPAD2:
				_amp--;
				if(_amp < 0)
					_amp = 0;
				break;
			case VK_SUBTRACT:
				_sTime++;
				if(_sTime > 50)
					_sTime = 50;
				break;
			case VK_ADD:
				_sTime--;
				if(_sTime < 10)
					_sTime = 10;
				break;
			case VK_RETURN:
				drawcirc();
				break;
			case 0x48:
				MessageBoxA(NULL, "NUMPAD + : Increase speed\n"
					 "NUMPAD - : Decrease speed\n"
					 "NUMPAD 8 : Increase amplitude\n"
					 "NUMPAD 2 : Decrease amplitude\n"
					 "NUMPAD 4 : Increase frequency\n"
					 "NUMPAD 6 : Decrease frequency\n"
					 "Return   : Draw a small circle\n"
					 "\nChanges are small, hold the button",
					 "Help", MB_OK);
				break;
			}
			return 0;
		} break;
     }
     return DefWindowProc(hWnd, message, wParam, lParam);
 }

void calcwave()
{
	static const double _full = 2 * pi;
	static double _x = 0;

	_yc._one._y = (sin(_x)*_amp) + 300;

	_x += 1.0 / _freq;
	if (_x >= _full)
		_x -= _full;

	_amplitude = "Amplitude : " + convstr(_amp * 2) + " pixels";
	_frequency = "Frequency : " + convstr(_full * _freq) + " pixels";
	_speed = "Speed : " + convstr(_sTime);
	
	drawwave();
	
	TextOutA(hDC, 5, 0, _amplitude.c_str(), _amplitude.size());
	TextOutA(hDC, 5, 17, _frequency.c_str(), _frequency.size());
	TextOutA(hDC, 5, 34, _speed.c_str(), _speed.size());

	_yc._two._y = _yc._one._y;
}

void drawwave()
{
	MoveToEx(hDC, _yc._two._x, _yc._two._y, NULL);
	LineTo(hDC, _yc._one._x, _yc._one._y);
	ScrollWindow(hWnd, -1, 0, &rect, NULL);
	Sleep(_sTime);
}

std::string convstr(const int& t)
{
	std::stringstream itoa;
	itoa << t;
	return itoa.str();
}

void drawcirc()
{
	circle a;
}
Use as many files as you have task areas. That's still fairly vague, but it's bound to be. Just use your discretion to get the best organisation.

For example, perhaps you could put all the code for computing a sine wave and related stuff in a separate file. When you are moving functions to a different file, remember that you shouldn't just dump them in a header. Make a whole separate source file.

Oh, and just a tip. You may as well have your program constants such as PI given as global constant variables rather than compiler macros. As a rule, I would use global constant variables and inline functions rather than compiler macros. (The latter *might* occasionally be slightly slower, but it hardly matters for most stuff).

#define PI 3.14 becomes const double PI = 3.14;
closed account (zwA4jE8b)
I don't know much about inline functions. Do you mean use __inline?

Also, when using a separate source '.cpp' file I have to put the function prototypes in a header correct?

or is there a way to access the other .cpp file?
closed account (zwA4jE8b)
void drawcirc(){circle a;}
use this in place of the function prototype as to eliminate lines 206-209?

is this...
inline void drawcircle(){for(double c = 1; c < 360; c+=6){SetPixel(hDC, _yc._one._x + std::cos(c)*5, _yc._one._y + sin(c)*5, blue);}
the same as...
1
2
3
4
5
inline void drawcircle()
	{
		for(double c = 1; c < 360; c+=6)
			SetPixel(hDC, _yc._one._x + std::cos(c)*5, _yc._one._y + sin(c)*5, blue);
	}


is the keyword inline needed if the function is declared and defined on one line?
Last edited on
The inline keyword is just inline.

Inline functions are not called when you call them, instead the code of the function is copied into the other code, inline. Note, however, that the inline keyword doesn't make a function inline, it merely suggests it to the compiler. The compiler can make inline functions non inline and non inline ones inline.

Basically, the purpose of the inline keyword is that if you put a function in a header file (which you must with inline ones as, traditionally at least, the compiler needs to see the source of the function to inline it. But if you do this you'll get multiply defined symbol errors from the linker. The inline keyword avoids these.

To 'access' the stuff in the other source file, you need to provide the prototypes. You can put these in a header and then include the header in both source files.

This:
1
2
3
4
5
6
7
void drawcirc(){circle a;}[/quote]
is not a function prototype. It is a full function. C++ ignores whitespace (mostly), so it is exactly the same as:
[code]
void drawcirc()
{
   circle a;
}

Similarly, your other two code segments are the same. Use the inline keyword if it is a small function that you wish to place inside the header file and (possibly) improve performance.

An example of replacing macros:
1
2
#define PI 3.14
#define ToRadians(x) x * PI / 180.0 

could become
1
2
3
4
5
6
const double PI = 3.14;

inline double ToRadians(double x)
{
   return x * PI / 180.0;
}
Topic archived. No new replies allowed.