docs/develop: Mass directory restructure.
Now vaguely follows the tree structure of "src", with the exception of directories that described subsystems spanning more than one "kit" or "server" (e.g. "media", "midi", "bluetooth") -- these have been left as their own top-level directory within docs/develop.
This commit is contained in:
@@ -0,0 +1,660 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>BPicture specifications</title>
|
||||
<meta http-equiv="content-type"
|
||||
content="text/html; charset=ISO-8859-1">
|
||||
<meta name="author" content="Marc Flerackers([email protected])">
|
||||
<meta name="description"
|
||||
content="BPicture specifications for OpenBeOS">
|
||||
</head>
|
||||
<body>
|
||||
<span style="font-weight: bold; text-decoration: underline;"></span>Author:
|
||||
Marc Flerackers<br>
|
||||
Revision: 1.4<br>
|
||||
<span style="font-weight: bold; text-decoration: underline;"></span><span
|
||||
style="font-weight: bold; text-decoration: underline;"><br>
|
||||
Picture data</span><br>
|
||||
<br>
|
||||
The data of a BPicture is composed of instructions.<br>
|
||||
<br>
|
||||
These instructions have a small header, which looks as follows:<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>int16</td>
|
||||
<td valign="top">id</td>
|
||||
<td valign="top">The instruction id</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">int32</td>
|
||||
<td valign="top">size</td>
|
||||
<td valign="top">The size of the data</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
After this header the data follows. There are two exceptions:
|
||||
EnterStateChange and EnterFontState. These are used to enclose state and
|
||||
font changes. For ExitStateChange and ExitFontState there are no
|
||||
instructions, this is not needed as we know the size of the instruction
|
||||
block in the header of the Enter* functions.<br>
|
||||
<br>
|
||||
These are the known instructions at the moment:<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left; width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th valign="top">Id<br>
|
||||
</th>
|
||||
<th valign="top">Name<br>
|
||||
</th>
|
||||
<th valign="top">Size<br>
|
||||
</th>
|
||||
<th valign="top">Data<br>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0010<br>
|
||||
</td>
|
||||
<td valign="top">MovePenBy<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">BPoint where<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0100<br>
|
||||
</td>
|
||||
<td valign="top">StrokeLine<br>
|
||||
</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BPoint start<br>
|
||||
BPoint end<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0101<br>
|
||||
</td>
|
||||
<td valign="top">StrokeRect<br>
|
||||
</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0102<br>
|
||||
</td>
|
||||
<td valign="top">FillRect<br>
|
||||
</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0103<br>
|
||||
</td>
|
||||
<td valign="top">StrokeRoundRect<br>
|
||||
</td>
|
||||
<td valign="top">24</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
BPoint radii<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0104<br>
|
||||
</td>
|
||||
<td valign="top">FillRoundRect</td>
|
||||
<td valign="top">24<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
BPoint radii</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0105<br>
|
||||
</td>
|
||||
<td valign="top">StrokeBezier<br>
|
||||
</td>
|
||||
<td valign="top">32<br>
|
||||
</td>
|
||||
<td valign="top">BPoint[4] control</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0106<br>
|
||||
</td>
|
||||
<td valign="top">FillBezier<br>
|
||||
</td>
|
||||
<td valign="top">32<br>
|
||||
</td>
|
||||
<td valign="top">BPoint[4] control</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010B<br>
|
||||
</td>
|
||||
<td valign="top">StrokePolygon<br>
|
||||
</td>
|
||||
<td valign="top">4 + point data size + 1<br>
|
||||
</td>
|
||||
<td valign="top">int32 numPoints<br>
|
||||
BPoint *points<br>
|
||||
bool isClosed<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010C<br>
|
||||
</td>
|
||||
<td valign="top">FillPolygon<br>
|
||||
</td>
|
||||
<td valign="top">4 + point data size </td>
|
||||
<td valign="top">int32 numPoints<br>
|
||||
BPoint *points<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010D<br>
|
||||
</td>
|
||||
<td valign="top">StrokeShape<br>
|
||||
</td>
|
||||
<td valign="top">shape data size<br>
|
||||
</td>
|
||||
<td valign="top">shape data, see below </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010E </td>
|
||||
<td valign="top">FillShape </td>
|
||||
<td valign="top">shape data size </td>
|
||||
<td valign="top">shape data, see below </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010F<br>
|
||||
</td>
|
||||
<td valign="top">DrawString<br>
|
||||
</td>
|
||||
<td valign="top">4 + string data size + 8<br>
|
||||
</td>
|
||||
<td valign="top">strlen<br>
|
||||
char *string<br>
|
||||
float deltax<br>
|
||||
float deltay<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0110 </td>
|
||||
<td valign="top">DrawPixels<br>
|
||||
</td>
|
||||
<td valign="top">56 + pixel data size<br>
|
||||
</td>
|
||||
<td valign="top">BRect src<br>
|
||||
BRect dest<br>
|
||||
int32 width<br>
|
||||
int32 height<br>
|
||||
int32 bytesPerRow<br>
|
||||
int32 pixelFormat<br>
|
||||
int32 flags<br>
|
||||
int32 length of pixel data<br>
|
||||
pixel data<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0112<br>
|
||||
</td>
|
||||
<td valign="top">DrawPicture<br>
|
||||
</td>
|
||||
<td valign="top">12<br>
|
||||
</td>
|
||||
<td valign="top">BPoint where?<br>
|
||||
????<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0113</td>
|
||||
<td valign="top">StrokeArc<br>
|
||||
</td>
|
||||
<td valign="top">24<br>
|
||||
</td>
|
||||
<td valign="top">BPoint center<br>
|
||||
BPoint radii<br>
|
||||
float startTheta<br>
|
||||
float arcTheta<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0114<br>
|
||||
</td>
|
||||
<td valign="top">FillArc<br>
|
||||
</td>
|
||||
<td valign="top">24<br>
|
||||
</td>
|
||||
<td valign="top">BPoint center<br>
|
||||
BPoint radii<br>
|
||||
float startTheta<br>
|
||||
float arcTheta</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0115<br>
|
||||
</td>
|
||||
<td valign="top">StrokeEllipse<br>
|
||||
</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0116</td>
|
||||
<td valign="top">FillEllipse</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0200<br>
|
||||
</td>
|
||||
<td valign="top">EnterStateChange<br>
|
||||
</td>
|
||||
<td valign="top">size of state instructions<br>
|
||||
</td>
|
||||
<td valign="top">state instructions</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0201</td>
|
||||
<td valign="top">SetClippingRects</td>
|
||||
<td valign="top">16 + size of rects<br>
|
||||
</td>
|
||||
<td valign="top">clipping_rect bound<br>
|
||||
clipping_rect *rect</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0202</td>
|
||||
<td valign="top">ClipToPicture</td>
|
||||
<td valign="top">7 + 8 + 1 </td>
|
||||
<td valign="top">zero bytes<br>
|
||||
BPoint pt<br>
|
||||
bool clip_to_inverse_picture<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0203<br>
|
||||
</td>
|
||||
<td valign="top">PushState<br>
|
||||
</td>
|
||||
<td valign="top">0<br>
|
||||
</td>
|
||||
<td valign="top"><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0204</td>
|
||||
<td valign="top">PopState</td>
|
||||
<td valign="top">0<br>
|
||||
</td>
|
||||
<td valign="top"><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0205<br>
|
||||
</td>
|
||||
<td valign="top">SetClippingRects </td>
|
||||
<td valign="top">0 </td>
|
||||
<td valign="top">This is a shorter instruction for 0 clipping
|
||||
rects.<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0300<br>
|
||||
</td>
|
||||
<td valign="top">SetOrigin<br>
|
||||
</td>
|
||||
<td valign="top">8<br>
|
||||
</td>
|
||||
<td valign="top">BPoint pt<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0301<br>
|
||||
</td>
|
||||
<td valign="top">SetPenLocation<br>
|
||||
</td>
|
||||
<td valign="top">8<br>
|
||||
</td>
|
||||
<td valign="top">BPoint pt<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0302<br>
|
||||
</td>
|
||||
<td valign="top">SetDrawingMode<br>
|
||||
</td>
|
||||
<td valign="top">2<br>
|
||||
</td>
|
||||
<td valign="top">drawing_mode mode<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0303</td>
|
||||
<td valign="top">SetLineMode<br>
|
||||
</td>
|
||||
<td valign="top">2 + 2 + 4<br>
|
||||
</td>
|
||||
<td valign="top">cap_mode capMode<br>
|
||||
join_mode joinMode<br>
|
||||
float miterLimit<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0304<br>
|
||||
</td>
|
||||
<td valign="top">SetPenSize</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float size<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0305<br>
|
||||
</td>
|
||||
<td valign="top">SetScale<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float scale</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0306<br>
|
||||
</td>
|
||||
<td valign="top">SetForeColor<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">rgb_color color<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0307<br>
|
||||
</td>
|
||||
<td valign="top">SetBackColor<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">rgb_color color</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0308<br>
|
||||
</td>
|
||||
<td valign="top">SetStipplePattern<br>
|
||||
</td>
|
||||
<td valign="top">8<br>
|
||||
</td>
|
||||
<td valign="top">pattern p<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0309<br>
|
||||
</td>
|
||||
<td valign="top">EnterFontState<br>
|
||||
</td>
|
||||
<td valign="top">size of font instructions</td>
|
||||
<td valign="top">font instructions</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x030A<br>
|
||||
</td>
|
||||
<td valign="top">SetBlendingMode<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">source_alpha alphaSrcMode<br>
|
||||
alpha_function alphaFncMode<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0380<br>
|
||||
</td>
|
||||
<td valign="top">SetFontFamily<br>
|
||||
</td>
|
||||
<td valign="top">4 + string data size</td>
|
||||
<td valign="top">strlen<br>
|
||||
char *family<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0381<br>
|
||||
</td>
|
||||
<td valign="top">SetFontStyle<br>
|
||||
</td>
|
||||
<td valign="top">4 + string data size</td>
|
||||
<td valign="top">strlen<br>
|
||||
char style</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0382<br>
|
||||
</td>
|
||||
<td valign="top">SetFontSpacing<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">int32 spacing<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0383<br>
|
||||
</td>
|
||||
<td valign="top">SetFontEncoding<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">int32 encoding<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0384<br>
|
||||
</td>
|
||||
<td valign="top">SetFontFlags<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">int32 flags<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0385<br>
|
||||
</td>
|
||||
<td valign="top">SetFontSize<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float size<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0386<br>
|
||||
</td>
|
||||
<td valign="top">SetFontRotate<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float rotation<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0387<br>
|
||||
</td>
|
||||
<td valign="top">SetFontShear<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float shear(is 0 instead of 90?)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0389<br>
|
||||
</td>
|
||||
<td valign="top">SetFontFace<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">int32 flags<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
There are a few undocumented instructions:<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left;" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top">0x0388<br>
|
||||
</td>
|
||||
<td valign="top">SetFontBPP </td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top"> int32 bpp (default 8)<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
Not all instructions where checked yet. The SetClippingRects has still
|
||||
to be documented.<br>
|
||||
<br>
|
||||
DrawPicture and ClipToPicture have an index to the sub-picture. In
|
||||
flattened data, these sub-pictures are stored in front of the main
|
||||
picture data, when archived to a BMessage, the sub-pictures are
|
||||
contained in a field called "piclib".<br>
|
||||
<br>
|
||||
<span style="font-weight: bold; text-decoration: underline;">Shape data</span><br>
|
||||
<br>
|
||||
The shape data contained in a BPicture is stored as follows:<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left;" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top">int32<br>
|
||||
</td>
|
||||
<td valign="top">instruction count<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" rowspan="1" colspan="1">uint32 *instructions<br>
|
||||
</td>
|
||||
<td valign="top" rowspan="1" colspan="1">Each instruction looks
|
||||
like:<br>
|
||||
First byte is the instruction id<br>
|
||||
The next three bytes is the amount of points used*<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">int32<br>
|
||||
</td>
|
||||
<td valign="top">point count<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">BPoint *points </td>
|
||||
<td valign="top">points<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left; width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th valign="top">Id<br>
|
||||
</th>
|
||||
<th valign="top">Name<br>
|
||||
</th>
|
||||
<th valign="top">Points*<br>
|
||||
</th>
|
||||
<th valign="top">Notes<br>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x80</td>
|
||||
<td valign="top">MoveTo</td>
|
||||
<td valign="top"><br>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>A "MoveTo" instruction doesn't stand alone, but is OR-ed
|
||||
with a "LineTo" or "BezierTo" instruction<br>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x10 </td>
|
||||
<td valign="top">LineTo</td>
|
||||
<td valign="top">point count in instruction<br>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>One "LineTo" instruction draws "count" lines</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x90 </td>
|
||||
<td valign="top">MoveTo LineTo</td>
|
||||
<td valign="top">point count in instruction + 1</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>There is one extra point for the "MoveTo", which is not
|
||||
counted in the instruction.<br>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x20 </td>
|
||||
<td valign="top">BezierTo</td>
|
||||
<td valign="top">point count in instruction</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>One "BezierTo" instruction draws "count" lines</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0xA0 </td>
|
||||
<td valign="top">MoveTo BezierTo</td>
|
||||
<td valign="top">point count in instruction + 1</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>There is one extra point for the "MoveTo", which is not
|
||||
counted in the instruction.<br>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x40 </td>
|
||||
<td valign="top">Close</td>
|
||||
<td valign="top">0 </td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>"Close" can only follow a "LineTo" or "BezierTo" instruction</li>
|
||||
<li>If an instruction follows "Close", the new instruction is
|
||||
OR-ed with "Close" and replaces it instruction</li>
|
||||
<li>A shape never starts with "Close"</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
Tests executed on a Duron 1200
|
||||
|
||||
ikki:~/projects/current# tests/UnitTester BRegion
|
||||
------------------------------------------------------------------------------
|
||||
Tests
|
||||
------------------------------------------------------------------------------
|
||||
BRegion::Construction Test
|
||||
+ PASSED
|
||||
Clock time: 0 ms
|
||||
|
||||
BRegion::Exclude Test
|
||||
+ PASSED
|
||||
Clock time: 251 ms
|
||||
|
||||
BRegion::Include Test
|
||||
+ PASSED
|
||||
Clock time: 260 ms
|
||||
|
||||
BRegion::Intersect Test
|
||||
+ PASSED
|
||||
Clock time: 102 ms
|
||||
|
||||
BRegion::OffsetBy Test
|
||||
+ PASSED
|
||||
Clock time: 0 ms
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Results
|
||||
------------------------------------------------------------------------------
|
||||
+ PASSED
|
||||
|
||||
|
||||
As you can see, it may be worth optimizing especially the Exclude and Include methods.
|
||||
See RegionSupport.cpp (in particular RSub() and ROr()) for more info.
|
||||
@@ -0,0 +1,30 @@
|
||||
Tests executed on a Duron 1200
|
||||
|
||||
ikki:~/projects/current# tests/UnitTester -r5 BRegion
|
||||
------------------------------------------------------------------------------
|
||||
Tests
|
||||
------------------------------------------------------------------------------
|
||||
BRegion::Construction Test
|
||||
+ PASSED
|
||||
Clock time: 0 ms
|
||||
|
||||
BRegion::Exclude Test
|
||||
+ PASSED
|
||||
Clock time: 284 ms
|
||||
|
||||
BRegion::Include Test
|
||||
+ PASSED
|
||||
Clock time: 265 ms
|
||||
|
||||
BRegion::Intersect Test
|
||||
+ PASSED
|
||||
Clock time: 113 ms
|
||||
|
||||
BRegion::OffsetBy Test
|
||||
+ PASSED
|
||||
Clock time: 0 ms
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Results
|
||||
------------------------------------------------------------------------------
|
||||
+ PASSED
|
||||
@@ -0,0 +1,391 @@
|
||||
<HTML>
|
||||
<!-- $Id: UnitTestingInfo.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
|
||||
<HEAD>
|
||||
<TITLE>Unit Testing Information</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
|
||||
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
|
||||
|
||||
<H1>Unit Testing Information:</H1>
|
||||
|
||||
<P>This document describes the "why's" and "how's" of unit testing for the AppKit team of the
|
||||
OpenBeOS project. Although it is intended for the AppKit team, there is no reason other teams
|
||||
couldn't use this information to develop a similar unit testing strategy.</P>
|
||||
|
||||
<P>The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#what">What is unit testing?</A></LI>
|
||||
<LI><A HREF="#why">Why is unit testing important?</A></LI>
|
||||
<LI><A HREF="#when">When should I write my unit tests?</A></LI>
|
||||
<LI><A HREF="#whattests">What kinds of tests should be in a unit test?</A></LI>
|
||||
<LI><A HREF="#testframework">What framework is being used to do unit testing for the AppKit?</A></LI>
|
||||
<LI><A HREF="#frameworkmods">What AppKit specific modifications have been made to this framework?</A></LI>
|
||||
<LI><A HREF="#futuremods">What framework modifications might be required in the future?</A></LI>
|
||||
<LI><A HREF="#buildingtests">How do I build the framework and current tests for the AppKit?</A></LI>
|
||||
<LI><A HREF="#runningtests">How do I run tests?</A></LI>
|
||||
<LI><A HREF="#writingtests">How do I write tests for my component?</A></LI>
|
||||
<LI><A HREF="#exampletests">Are there example tests to base mine on?</A></LI>
|
||||
<LI><A HREF="#threadedtests">How do I write a test with multiple threads?</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="what"></A><H2>What is unit testing?</H2>
|
||||
|
||||
<P>Unit testing is the process of showing that a part of a software system works as far as the
|
||||
requirements created for that part of the system. Unit testing is best if it has the following
|
||||
characteristics:</P>
|
||||
|
||||
<UL>
|
||||
<LI>The software component is tested in isolation with as little interaction with other software
|
||||
components as possible.</LI>
|
||||
<LI>The software component is tested using automated tools so that unit tests can be run with
|
||||
every build of the software if required.</LI>
|
||||
<LI>All requirements of the software component are tested as part of the unit tests.</LI>
|
||||
</UL>
|
||||
|
||||
<P>Unit testing is not the only type of testing but is definitely a very important part of any
|
||||
testing strategy. Following unit testing, software should go through "integration testing" to
|
||||
show that the components work as expected when put together.</P>
|
||||
|
||||
<A NAME="why"></A><H2>Why is unit testing important?</H2>
|
||||
|
||||
<P>A basic concept of software engineering is that the cost of fixing a bug goes up by a factor
|
||||
of 2-10x (depending on the source of the information) the later in the development process it is
|
||||
found. Unit testing is critical to finding implementation bugs within a particular component as
|
||||
quickly as possible.</P>
|
||||
|
||||
<P>Unit testing will also help to find requirements problems also. If you write the requirements
|
||||
(or use cases) for your component from the BeBook, hopefully the BeBook and your use cases will
|
||||
match the actual Be implementation. A good way to confirm that the BeBook documentation matches
|
||||
Be's implementation is to write your unit tests and run them against the original Be code.</P>
|
||||
|
||||
<P>Unit tests will also continue to be maintained and run in the future also. As the mailing
|
||||
lists obviously show, many people are looking forward to OpenBeOS post-R1 when new features
|
||||
will be introduced above and beyond BeOS R5. These unit tests will be critical to ensuring that
|
||||
any new feature or even just a bug fix doesn't break existing functionality.</P>
|
||||
|
||||
<P>Speaking of bug fixes, consider adding unit tests for any bugs you identify that slipped
|
||||
through your original unit test suite. This will ensure that this bug or a similar one is not
|
||||
re-introduced in the future.</P>
|
||||
|
||||
<P>Finally, unit testing is not the be all, end all of testing. As mentioned above, integration
|
||||
testing must be done to show that software components work together. If all unit tests cover
|
||||
all requirements and have run successfully against all components, then a failure has to be
|
||||
due to a bug in the interaction of two or more known working software components.</P>
|
||||
|
||||
<A NAME="when"></A><H2>When should I write my unit tests?</H2></LI>
|
||||
|
||||
<P>As the AppKit process document describes the recommended order for implementing a component
|
||||
is:</P>
|
||||
|
||||
<OL>
|
||||
<LI>Write an interface specification</LI>
|
||||
<LI>Write the use case specifications</LI>
|
||||
<LI>Write the unit tests</LI>
|
||||
<LI>Write an implementation plan</LI>
|
||||
<LI>Write the code</LI>
|
||||
</OL>
|
||||
|
||||
<P>Please see the AppKit process document for more details about the entire sequence. The unit
|
||||
test are to be written once the use cases are written and before any implementation work is
|
||||
done. The use cases must be done because they determine what the tests will be. You need to
|
||||
write as many tests are required so that all use cases for that component are tested. The use
|
||||
cases should be detailed enough that you can write your unit tests from them.</P>
|
||||
|
||||
<P>The unit tests are to be done before implementation for a very good reason. You should be able
|
||||
to run these unit tests against the Be implementation and confirm that they all pass. If they do
|
||||
not pass, then either there is a bug in the unit test itself or you have found a difference
|
||||
between your use cases and the actual implementation. Even if your use cases match the BeBook,
|
||||
if that is not how the actual Be implementation works, we must match the current implementation and
|
||||
not the BeBook. You should go back and modify the use case. Change the use case so that it
|
||||
matches Be's implementation and consider adding a note indicating this doesn't match the
|
||||
BeBook.</P>
|
||||
|
||||
<P>Imagine if you completed the implementation and then wrote and ran the unit tests. If you run
|
||||
the tests against your implementation and Be's implementation, you will notice the test passes
|
||||
for your code but fails on Be's. At this point, you will have to change the implementation, change
|
||||
the unit test and change the use case which is more work that if you write the unit tests before
|
||||
the implementation. Worse, if you only ran the unit tests against your implementation and not
|
||||
Be's, you may not notice the problem at all.</P>
|
||||
|
||||
<A NAME="whattest"></A><H2>What kinds of tests should be in a unit test?</H2>
|
||||
|
||||
<P>The unit tests you write should cover all the functionality of your software module. That
|
||||
means your unit tests should include:</P>
|
||||
|
||||
<UL>
|
||||
<LI>All standard expected functionality of the software component</LI>
|
||||
<LI>All error conditions handled by the software component</LI>
|
||||
<LI>Interaction with software components which cannot be decoupled from the target software
|
||||
component</LI>
|
||||
<LI>Concurrency tests to show that a software component which is expected to be thread safe (most
|
||||
things are under BeOS) is safe and free from deadlocks.</LI>
|
||||
</UL>
|
||||
|
||||
<A NAME="testframework"></A><H2>What framework is being used to do unit testing for the AppKit?</H2>
|
||||
|
||||
<P>The AppKit team has chosen to use CppUnit version 1.5 as the basis of all of our unit tests.
|
||||
This framework provides very useful features and ensures that all unit tests for AppKit code
|
||||
are consistent and can be executed from a single environment.</P>
|
||||
|
||||
<P>There are two key components to the framework. First, there is a library called libCppUnit.so
|
||||
which provides all the C++ classes for defining your own testcases. Secondly, there is an
|
||||
executable called "TestRunner" which is capable of executing a set of testcases.</P>
|
||||
|
||||
<P>For more information on CppUnit, please refer to
|
||||
<A HREF="http://cppunit.sourceforge.net/">this website</A>
|
||||
|
||||
<A NAME="frameworkmods"></A><H2>What AppKit specific modifications have been made to this framework?</H2>
|
||||
|
||||
<P>The following are the modifications that have been introduced into the CppUnit v1.5
|
||||
framework:</P>
|
||||
|
||||
<UL>
|
||||
<LI>A makefile has been added for the library and the TestRunner.</LI>
|
||||
<LI>Some "bugs" in CppUnit v1.5 which lead to it not compiling under BeOS v5.</LI>
|
||||
<LI>The TestRunner has been modified to support BeOS based addons. Each test which you can
|
||||
select from the TestRunner is found in the "add-ons" directory at runtime. The original
|
||||
TestRunner required you to change the TestRunner when new tests were added to it.</LI>
|
||||
<LI>Changed the output from TestRunner. The output includes a name of the test being run and
|
||||
a run time for the test in microseconds.</LI>
|
||||
<LI>Changed the arguments of the assert functions in the TestCase class from std::string to
|
||||
const char *'s due to apparent concurrency problems with std::string under BeOS when testing
|
||||
threaded tests.</LI>
|
||||
<LI>Added locking to the TestResults class so that multiple threads can safely add result
|
||||
information at the same time for a single test.</LI>
|
||||
<LI>The ThreadedTestCaller class was written to allow us to write tests which contain multiple
|
||||
threads. This is an important class because many BeOS components are thread safe and we need
|
||||
to confirm that the OpenBeOS implementation is also thread safe.</LI>
|
||||
</UL>
|
||||
|
||||
<P>This is the list of the important modifications done to CppUnit v1.5 at the time this document
|
||||
is being written. For the latest information about modifications to CppUnit, check the code
|
||||
which can be found in the OpenBeOS CVS repository.</P>
|
||||
|
||||
<A NAME="futuremods"></A><H2>What framework modifications might be required in the future?</H2>
|
||||
|
||||
<P>This framework will have to evolve as our needs grow. The main issues I think we need to
|
||||
solve are:</P>
|
||||
|
||||
<UL>
|
||||
<LI>The format of the test name is an encoded string representing the class definition of the
|
||||
test class from gcc. It is not a very readable format but given that the test class is often
|
||||
a template class and you would like different names for different instances of the template,
|
||||
this seemed the best compromise. Suggestions welcome.</LI>
|
||||
|
||||
<LI>The threaded test support added into CppUnit forces you to specify the entry point for each
|
||||
thread in your test. If you are doing a test with a BLooper or a BWindow, these classes start
|
||||
a thread of their own. This thread will not be started through the standard entry point so
|
||||
doing "assert's" from one of these threads will not work. Perhaps we need TestBLooper and
|
||||
TestBWindow classes which will work with the assert's.</LI>
|
||||
</UL>
|
||||
|
||||
<P>If you find you need some other features, feel free to add them to CppUnit.</P>
|
||||
|
||||
<A NAME="buildingtests"></A><H2>How do I build the framework and current tests for the AppKit?</H2>
|
||||
|
||||
<P>As of writing this document, you can build the framework and all the current AppKit tests
|
||||
by performing the following steps:</P>
|
||||
|
||||
<OL>
|
||||
|
||||
<LI>Checkout the "app_kit" sources or the entire repository from the OpenBeOS CVS repository.
|
||||
There is information at the OpenBeOS site about how to access the CVS repository.</LI>
|
||||
|
||||
<LI>In a terminal, "cd" into the "app_kit" directory in the CVS files you checked out.</LI>
|
||||
|
||||
<LI>Type "make".</LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<P>Note that the build system for OpenBeOS is moving to jam so these steps may become obsolete.
|
||||
When you the make has finished, you should find the following files:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><CODE>app_kit/test/CppUnit/TestRunner</CODE> - this is the executable to use to execute
|
||||
tests.</LI>
|
||||
<LI><CODE>app_kit/test/CppUnit/lib/libCppUnit.so</CODE> - this is CppUnit library which your tests
|
||||
must link against.</LI>
|
||||
<LI><CODE>app_kit/test/CppUnit/lib/libopenbeos.so</CODE> - this is library which contains OpenBeOS
|
||||
implementation of some Be classes (usually found in libbe.so, called libopenbeos.so to avoid a name
|
||||
clash at runtime).</LI>
|
||||
<LI><CODE>app_kit/test/add-ons/BAutolockTests</CODE> - this is the addon which contains the tests
|
||||
which are run against the Be and OpenBeOS implementation of BAutolock.</LI>
|
||||
<LI><CODE>app_kit/test/add-ons/BLockerTests</CODE> - this is the addon which contains the tests
|
||||
which are run against the Be and OpenBeOS implementation of BLocker.</LI>
|
||||
<LI><CODE>app_kit/test/add-ons/BMessageQueueTests</CODE> - this is the addon which contains the tests
|
||||
which are run against the Be and OpenBeOS implementation of BMessageQueue.</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>These are the key files which ensure that the tests can be run.</P>
|
||||
|
||||
<A NAME="runningtests"></A><H2>How do I run tests?</H2>
|
||||
|
||||
<P>You have a few different options for how you run a test or a series of tests. Before you start
|
||||
however, you must build the code as describe <A HREF="#buildingtests">in this section</A>. Once
|
||||
it is built, you can run tests any of these ways:</P>
|
||||
|
||||
<UL>
|
||||
<LI>Run "make test" from the app_kit directory. This will lead to all of the tests defined in
|
||||
app_kit/test/add-ons directory to be run.</LI>
|
||||
<LI>From the "app_kit/test" directory, execute the command "CppUnit/TestRunner -all". This will
|
||||
lead to all of the tests defined in the app_kit/test/add-ons directory to be run and is the same
|
||||
as what happens in the "make" example above. However, recompile any code that has changed in the
|
||||
process.</LI>
|
||||
<LI>From the "app_kit/test" directory, execute the command "CppUnit/TestRunner <TestName>"
|
||||
where <TestName> is one of the addons found in the "app_kit/test/add-ons" directory. Only
|
||||
the tests defined in that add-on will be run.</LI>
|
||||
</UL>
|
||||
|
||||
<A NAME="writingtests"></A><H2>How do I write tests for my component?</H2>
|
||||
|
||||
<P>The first step to writing your tests is to develop a plan for how you will test the
|
||||
functionality. For ideas of the kinds of tests you may want to consider, you should reference
|
||||
<A HREF="#whattests">this section</A>.</P>
|
||||
|
||||
<P>Once you know the kinds of tests you want, you need to:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><P>For every test you want, define a class which derives from the "TestCase" class in the
|
||||
CppUnit framework.</P></LI>
|
||||
|
||||
<LI><P>Within each test class you define, create a "void setUp(void)" and "void tearDown(void)"
|
||||
member function if required. If before executing your test, you need to perform some actions,
|
||||
put those actions in the "setUp()" member. If you need to cleanup after your test, put those
|
||||
actions in the "tearDown()" member.</P></LI>
|
||||
|
||||
<LI><P>Within each test class you define, create a member function which takes "void" and
|
||||
returns "void". Within this member function, write the code to execute the test. Whenever you
|
||||
want to ensure that some condition is true during your test, add a line within the member function
|
||||
that looks like "assert(condition)". For example, if the variable "result" must have the value
|
||||
B_OK at a particular point in your test, you should add a line which reads
|
||||
"assert(result = B_OK)".</P></LI>
|
||||
|
||||
<LI><P>Create a constructor for all of your test classes that takes a "std::string name" argument
|
||||
and pass that onto the TestCase parent class. Add whatever actions you need to take in the
|
||||
constructor.</P></LI>
|
||||
|
||||
<LI><P>Create a destructor for all of your test classes and take whatever actions are
|
||||
appropriate.</P></LI>
|
||||
|
||||
<LI><P>Within each test class you define, create a member with the signature
|
||||
"static Test *suite(void)". For a simple test where only one test needs to be run for this class,
|
||||
the contents of this member should look like:</P>
|
||||
|
||||
<PRE>
|
||||
return(new TestCaller<ClassName>("", &ClassName::MemberName));
|
||||
</PRE>
|
||||
|
||||
<P>Replace "ClassName" with the name of your test class and "MemberName" with the name
|
||||
of the member function you defined your test in. If you need to define more than one test to run
|
||||
from this class, refer to instructions below on how to use the TestSuite class of CppUnit. If you
|
||||
are creating a threaded test, refer to <A HREF="#threadedtests">this section</A>.</P></LI>
|
||||
|
||||
<LI><P>Create one ".cpp" file for defining the "addonTestFunc()" function. This function must
|
||||
exist in global scope within your test addon. The contents of this ".cpp" file will look something
|
||||
like:</P>
|
||||
|
||||
<PRE>
|
||||
#include "TestAddon.h"
|
||||
|
||||
Test *addonTestFunc(void)
|
||||
{
|
||||
TestSuite *testSuite = new TestSuite("<TestSuiteName>");
|
||||
|
||||
testSuite->addTest(<ClassName1>::suite());
|
||||
testSuite->addTest(<ClassName2>::suite());
|
||||
/* etc */
|
||||
|
||||
return(testSuite);
|
||||
}
|
||||
</PRE>
|
||||
|
||||
<P>In the above example, replace <TestSuiteName> with an appropriate name for the group of
|
||||
tests and <ClassName1> and <ClassName2> with the names of the test classes you have
|
||||
defined.</P></LI>
|
||||
|
||||
<LI><P>Create a build system around a BeIDE project, Makefile or preferrably a jam file which
|
||||
builds all the necessary code you have written into an addon.</P></LI>
|
||||
|
||||
<LI><P>Put this addon into the app_kit/test/add-ons directory and follow the above instructions
|
||||
for how to run your tests.</P></LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<A NAME="exampletests"></A><H2>Are there example tests to base mine on?</H2>
|
||||
|
||||
<P>There are example tests which you can find in the following directories:</P>
|
||||
|
||||
<UL>
|
||||
<LI><CODE>app_kit/test/lib/application/BMessageQueue</CODE></LI>
|
||||
<LI><CODE>app_kit/test/lib/support/BAutolock</CODE></LI>
|
||||
<LI><CODE>app_kit/test/lib/support/BLocker</CODE></LI>
|
||||
</UL>
|
||||
|
||||
<P>There are some things done in these tests which make things a bit more complex, but you may
|
||||
want to do similar things:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>Most tests use a ThreadedTestCaller class even in some situations when there aren't actually
|
||||
more than one thread in the test.</LI>
|
||||
|
||||
<LI>All tests are defined as a template class. The test class is a template of the class to test
|
||||
(if that makes sense to you). For example, to test both the Be and OpenBeOS BLocker and not
|
||||
end up with a symbol conflict, the OpenBeOS implementation of BLocker is actually in a namespace
|
||||
called "OpenBeOS". So, the tests must be run against the classes "::BLocker" and
|
||||
"OpenBeOS::BLocker". The easiest way to do this was to make the class to be tested a template
|
||||
and define it for both "::BLocker" and "OpenBeOS::BLocker".</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>Even with the complexity, I think this code provides a pretty good example of how to write
|
||||
your tests.</P>
|
||||
|
||||
<A NAME="threadedtests"></A><H2>How do I write a test with multiple threads?</H2>
|
||||
|
||||
<P>If you have a test which you want to define that requires more than one thread of execution
|
||||
(most likely a concurrency test of you code), you need to use the ThreadedTestCaller class.
|
||||
The steps which differ from the above description on how to write a test case are:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><P>In your test class, define a member function for each thread you will be starting. All of
|
||||
these member functions must take "void" and return "void". If all the threads in your test
|
||||
perform the exact same actions, it is OK to just define one member function. Usually in the
|
||||
tests I have written, I have called these member functions "TestThread1()", "TestThread2()",
|
||||
etc.</P></LI>
|
||||
|
||||
<LI><P>If your "static Test *suite()" function for your test class, you must return a
|
||||
ThreadedTestCaller. Imagine that the test class name is "MyTestClass" and you want two threads
|
||||
which run member functions "TestThread1()" and "TestThread2()". That code would look like:</P>
|
||||
|
||||
<PRE>
|
||||
Test *MyTestClass::suite(void)
|
||||
{
|
||||
MyTestClass *theTest = new MyTestClass("");
|
||||
ThreadedTestCaller<MyTestClass> *threadedTest = new TreadedTestCaller<MyTestClass>("", theTest);
|
||||
|
||||
threadedTest->addThread(":Thread1", &MyTestClass::TestThread1);
|
||||
threadedTest->addThread(":Thread2", &MyTestClass::TestThread2);
|
||||
|
||||
return(threadedTest);
|
||||
}
|
||||
</PRE>
|
||||
|
||||
<P>If you need to, you can put a number of ThreadedTestCaller instances into a TestSuite and return
|
||||
them in the suite() member function. Examples of this can be found in the BLocker and
|
||||
BMessageQueue test examples.</P></LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>Otherwise the steps are the same as for other tests. The code gets much more complex if you
|
||||
define your test classes as templates as the examples do.</P>
|
||||
|
||||
</FONT>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,341 @@
|
||||
<HTML>
|
||||
<!-- $Id: BDeskbarUseCases.html 1185 2002-09-26 02:21:31Z jrand $ -->
|
||||
<HEAD>
|
||||
<TITLE>BDeskbar Use Cases and Implementation Details</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
|
||||
|
||||
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
|
||||
|
||||
<H1>BDeskbar Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BDeskbar interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BDeskbar Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BDeskbar Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BDeskbar Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BDeskbar Interface:</H2>
|
||||
|
||||
<P>The BDeskbar class is a simple class for getting information from the deskbar and for modifying
|
||||
it from your application. The best source of source of information for the BDeskbar interface can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/Deskbar/Deskbar.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BDeskbar Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BDeskbar functionality:</P>
|
||||
|
||||
<OL>
|
||||
<LI><P><B>Construction:</B> A BDeskbar does not take any arguments when it is constructed. The
|
||||
BDeskbar instance creates a connection to the deskbar in order to get and change its state.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction:</B> When a BDeskbar is deconstructed, the application's connection to the
|
||||
deskbar is closed. However any change to the deskbar's state made through the BDeskbar instance
|
||||
persists.</P></LI>
|
||||
|
||||
<LI><P><B>Add Item 1:</B> The AddItem() member function can be used to take a passed in pointer to
|
||||
a BView and send it to the deskbar for inclusion in its shelf. This BView must be archivable
|
||||
and must be exported by the application (for details on how to do this,
|
||||
<A HREF="http://bedriven.be-in.org/articles/replicant/III_027-stepping%20up%20to%20the%20deskbar.html">this article</A>
|
||||
may help). The item will be added and the id of the new item will be passed back to the caller
|
||||
through a pointer to an int32.</P></LI>
|
||||
|
||||
<LI><P><B>Add Item 2:</B> The AddItem() member function can be used to add an item to the deskbar
|
||||
shelf by passing a pointer to an entry_ref. The file pointed to by this entry_ref should be
|
||||
an addon that exports the symbol "BView *instantiate_deskbar_item()". This entry point is used to
|
||||
get a BView which it can display in the shelf. More information on this mechanism can be found in
|
||||
the <A HREF="file:///boot/beos/documentation/Be%20Book/Release%20Notes/Deskbar.html">Deskbar Release Notes</A>
|
||||
but not in the Be Book proper. The item id of the added item is passed back in an int32 pointer
|
||||
provided by the caller. NOTE: The source code for the deskbar found in
|
||||
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/StatusView.cpp?rev=1.5&content-type=text/vnd.viewcvs-markup">TReplicantTray::LoadAddon()</A>
|
||||
indicates that it also looks for a symbol called "BView *instantiate_deskbar_entry(image_id, entry_ref *)"
|
||||
first, but there is no documentation on this.</P></LI>
|
||||
|
||||
<LI><P><B>Remove Item 1:</B> The RemoveItem() member function takes an integer id and removes it
|
||||
from the deskbar shelf if it exists. The member returns B_OK at all times (unless the deskbar is
|
||||
not running or some communication failure occurs). A B_OK result does not mean that an item was
|
||||
actually removed.</P></LI>
|
||||
|
||||
<LI><P><B>Remove Item 2:</B> The RemoveItem() member function also takes a string name and removes
|
||||
it from the deskbar shelf if it exists. The member returns B_OK at all times (unless the deskbar is
|
||||
not running or some communication failure occurs). A B_OK result does not mean that an item was
|
||||
actually removed.</P></LI>
|
||||
|
||||
<LI><P><B>Count Items:</B> The CountItems() member function takes no arguments. It returns the
|
||||
number of "items" in the deskbar shelf. For example, the small email icon often found in the
|
||||
deskbar is one such item.</P></LI>
|
||||
|
||||
<LI><P><B>Has Item 1:</B> The HasItem() member function takes a integer id and returns a true or
|
||||
false value which indicates whether or not an item exists in the deskbar shelf on that id. For
|
||||
example, the small email icon often found in the deskbar is one such item.</P></LI>
|
||||
|
||||
<LI><P><B>Has Item 2:</B> The HasItem() member function also takes a string name parameter and
|
||||
returns a true or false value which indicates whether or not an item by than name exists in
|
||||
the deskbar shelf. For example, the small email icon often found in the deskbar is named
|
||||
"mail".</P></LI>
|
||||
|
||||
<LI><P><B>Get Item Info 1:</B> The GetItemInfo() member function takes an integer id and a pointer
|
||||
to a const char * (ie a string). It checks to see if the id passed in exists in the deskbar and
|
||||
sets the value of the const char * to point to a allocated buffer which contains the name of the
|
||||
item which corresponds to this id and the function returns B_OK. Ownership of this allocated
|
||||
buffer is assigned to the caller of this member function so it is up to the caller to free the
|
||||
memory. If the id doesn't exist, then it still returns B_OK but the pointer to the string is set
|
||||
to NULL. If the pointer to the string passed in is NULL, the function returns B_BAD_VALUE.</P></LI>
|
||||
|
||||
<LI><P><B>Get Item Info 2:</B> The GetItemInfo() member also takes a string (const char *) name
|
||||
and a pointer to an int. If the name matches an item in the deskbar shelf, the id of this
|
||||
item is returned at the location pointed to by the integer pointer and the member returns B_OK.
|
||||
If the name doesn't match an item in the deskbar shelf, the id is set to -1. If the pointer
|
||||
passed in is NULL, the function returns B_BAD_VALUE.</P></LI>
|
||||
|
||||
<LI><P><B>Frame:</B> The Frame() member function returns a BRect which describes the location and
|
||||
size of the deskbar on the screen.</P></LI>
|
||||
|
||||
<LI><P><B>Location:</B> The Location() member function returns one of B_DESKBAR_TOP,
|
||||
B_DESKBAR_BOTTOM, B_DESKBAR_LEFT_BOTTOM, B_DESKBAR_RIGHT_BOTTOM, B_DESKBAR_LEFT_TOP or
|
||||
B_DESKBAR_RIGHT_TOP. The return value describes where the deskbar currently is located. Also,
|
||||
the Location() member function takes an optional argument which is a pointer to a boolean.
|
||||
If supplied, the boolean which is pointed to is set to true if the deskbar is expanded and false
|
||||
otherwise. A deskbar can only be contracted (ie not expanded) when in the left or right top
|
||||
position.</P></LI>
|
||||
|
||||
<LI><P><B>Is Expanded:</B> The IsExpanded() member function returns true if the deskbar is
|
||||
expanded and false if it is contracted. Note, the deskbar can only be contracted when in
|
||||
left or right top position.</P></LI>
|
||||
|
||||
<LI><P><B>Set Location:</B> The SetLocation() member function takes the same values returned
|
||||
by the Location() member. The value passed in the first argument sets the position of the deskbar.
|
||||
If the optional second argument is supplied, it is a boolean which indicates whether or not the
|
||||
deskbar is expanded (true) or contracted (false). Note, the deskbar can only be contracted when in
|
||||
left or right top position.</P></LI>
|
||||
|
||||
<LI><P><B>Expand:</B> The Expand() member function takes a single boolean argument which sets the
|
||||
deskbar to expanded (true) or contracted (false) mode. Note, the deskbar can only be contracted
|
||||
when in left or right top position.</P></LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BDeskbar Implementation:</H2>
|
||||
|
||||
<P>Internally, the BDeskbar uses a BMessenger to communicate with the deskbar itself.
|
||||
The source code from the OpenTracker project will be used as a reference for this effort.
|
||||
You can find the deskbar source code here:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/">http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/</A>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>Specifically, the code which handles communicating with the BDeskbar class can be found
|
||||
here:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup</A>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>The following describes the messages used to communicate between BDeskbar and the deskbar
|
||||
itself.</P>
|
||||
|
||||
|
||||
<H3>AddItem:</H3>
|
||||
|
||||
<P>The AddItem() member sends the following message to the deskbar to add an item from an
|
||||
archived BView:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
BMessage viewMsg;
|
||||
theView.Archive(&viewMsg); // This takes the target BView to place in the shelf and archives it into viewMsg
|
||||
theMsg.what = 'icon'
|
||||
theMsg.AddMessage("view", &viewMsg); // This puts the archived view in the viewMsg and puts it in the message to the deskbar
|
||||
</PRE>
|
||||
|
||||
<P>Or, the AddItem() member sends the following message to the deskbar to add an item from a file
|
||||
that exports the "BView *instantiate_deskbar_item(void)" function:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'adon'
|
||||
theMsg.AddRef("addon", &theAddonRef); // This is the addon which contains the hook function to get the view to add
|
||||
</PRE>
|
||||
|
||||
<P>The /boot/app/Pulse application exports the necessary symbol for this mechanism to work and
|
||||
is a good candidate to test with.</P>
|
||||
|
||||
<P>In either case, the deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.AddInt32("id", theID); // This is the id of the new item
|
||||
</PRE>
|
||||
|
||||
<P>Note that in both cases, the deskbar does not set the what code of the reply. Checking the
|
||||
source code for
|
||||
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::AddItem()</A>
|
||||
confirms this.
|
||||
|
||||
|
||||
<H3>HasItem:</H3>
|
||||
|
||||
<P>The HasItem() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'exst'
|
||||
theMsg.AddInt32("id", theID); // This is the id to check for
|
||||
// OR, only one of id or name should be in the message
|
||||
theMsg.AddString("name", theName); // This is the name to check for
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.AddBool("exists", IDorNameExists()); // This is a true/false value which indicates whether or not the name/id exists in the shelf
|
||||
</PRE>
|
||||
|
||||
<P>Note that the deskbar does not set the what code of the reply. Checking the source code
|
||||
for
|
||||
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::ItemExists()</A>
|
||||
confirms this.</P>
|
||||
|
||||
|
||||
<H3>GetItemInfo:</H3>
|
||||
|
||||
<P>The GetItemInfo() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'info'
|
||||
theMsg.AddInt32("id", theID); // This is the id to check for
|
||||
// OR, only one of id or name should be in the message
|
||||
theMsg.AddString("name", theName); // This is the name to check for
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.AddString("name", theName); // This is the name corresponding to the id of the original request
|
||||
// OR, only one of id or name should be in the response message depending on the request sent
|
||||
theMsg.AddInt32("id", theID); // This is the id corresponding to the name of the original request
|
||||
</PRE>
|
||||
|
||||
<P>Note that the deskbar does not set the what code of the reply. Checking the source code
|
||||
for
|
||||
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::ItemInfo()</A>
|
||||
confirms this.</P>
|
||||
|
||||
|
||||
<H3>CountItems:</H3>
|
||||
|
||||
<P>The CountItems() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'cwnt'
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'rply'; // This means reply
|
||||
theMsg.AddInt32("count", ItemCount()); // This is the number of items in the deskbar shelf
|
||||
</PRE>
|
||||
|
||||
|
||||
<H3>RemoveItem:</H3>
|
||||
|
||||
<P>The RemoveItem() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'remv'
|
||||
theMsg.AddInt32("id", theID); // This is the id to remove
|
||||
// OR, only one of id or name should be in the message
|
||||
theMsg.AddString("name", theName); // This is the name to remove
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar does not send a response.</P>
|
||||
|
||||
|
||||
<H3>Frame:</H3>
|
||||
|
||||
<P>The Frame() member sends a standard scripting message to get the frame from the deskbar. It
|
||||
sends a B_GET_PROPERTY message to the deskbar asking for the "Frame" property specifying the
|
||||
window by name. The window name is "Deskbar".</P>
|
||||
|
||||
<P>The response from deskbar has a what code of B_REPLY and a BRect describing the frame in a
|
||||
value called "result". This is standard BeOS scripting.</P>
|
||||
|
||||
|
||||
<H3>Location:</H3>
|
||||
|
||||
<P>The Location() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'gloc'; // This means get location
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'rply'; // This means reply
|
||||
theMsg.AddInt32("location", DeskbarLocation()); // This is the number which represents the location of the deskbar
|
||||
theMsg.AddBool("expanded", Expanded()); // This is true if the deskbar is expanded, false otherwise
|
||||
</PRE>
|
||||
|
||||
|
||||
<H3>IsExpanded:</H3>
|
||||
|
||||
<P>The IsExpanded() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'gexp'; // This means get expanded state
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'rply'; // This means reply
|
||||
theMsg.AddBool("expanded", Expanded()); // This is true if the deskbar is expanded, false otherwise
|
||||
</PRE>
|
||||
|
||||
|
||||
<H3>SetLocation:</H3>
|
||||
|
||||
<P>The SetLocation() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'sloc'; // This means set location
|
||||
theMsg.AddInt32("location", newLocation); // This is the number which represents the location of the deskbar
|
||||
theMsg.AddBool("expand", isExpanded); // This is true if the deskbar is expanded, false otherwise
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar does not send a reply to this message.</P>
|
||||
|
||||
|
||||
<H3>Expand:</H3>
|
||||
|
||||
<P>The Expand() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'sexp'; // This means set expanded state
|
||||
theMsg.AddBool("expand", isExpanded); // This is true if the deskbar is expanded, false otherwise
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar does not send a reply to this message.</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,89 @@
|
||||
<HTML>
|
||||
<!-- $Id: BPolygonUseCases.html 1727 2002-10-28 02:50:08Z jrand $ -->
|
||||
<HEAD>
|
||||
<TITLE>BPolygon Use Cases and Implementation Details</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
|
||||
|
||||
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
|
||||
|
||||
<H1>BPolygon Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BPolygon interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BPolygon Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BPolygon Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BPolygon Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BPolygon Interface:</H2>
|
||||
|
||||
<P>The BPolygon class is used to hold information about a shape composed of a series of straight
|
||||
lines (ie a polygon). On its own, it just describes the shape and can only be drawn by passing
|
||||
it to a BView. The best source of source of information for the BPolygon interface can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Interface%20Kit/Polygon.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BPolygon Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BPolygon functionality:</P>
|
||||
|
||||
<OL>
|
||||
<LI><P><B>Construction 1:</B> A BPolygon can be constructed without passing it any arguments. When
|
||||
this is done, the polygon will have no points in it (ie no shape) until they are added through
|
||||
AddPoints().</P></LI>
|
||||
|
||||
<LI><P><B>Construction 2:</B> A BPolygon can be constructed by passing it a pointer to an existing
|
||||
BPolygon (ie a copy constructor). The resulting copy will have the exact same state as the
|
||||
one passed in. That means it will have the same number of points in the same locations resulting
|
||||
in the same shape.</P></LI>
|
||||
|
||||
<LI><P><B>Construction 3:</B> A BPolygon can be constructed by passing it a pointer to an array of
|
||||
BPoints and an integer which describes the number of points in that array. The BPolygon will be
|
||||
constructed such that it holds the shape described by that array of points.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction:</B> When a BPolygon is deconstructed any memory allocated in order to hold
|
||||
the state of the BPolygon is freed and the state of the polygon is lost.</P></LI>
|
||||
|
||||
<LI><P><B>Add Points:</B> The AddPoints() member function appends a number of passed in points to
|
||||
the existing set of points already in the polygon. It takes a pointer to an array of BPoints and
|
||||
an integer count of the number of points to append. This is similar to the "Construction 3" use
|
||||
case except in that case there is no existing points so the passed in points describe the entire
|
||||
polygon.</P></LI>
|
||||
|
||||
<LI><P><B>Count Points:</B> The CountPoints() member function returns the number of points which
|
||||
describe the polygon. The result is an integer.</P></LI>
|
||||
|
||||
<LI><P><B>Frame:</B> The Frame() member function returns the smallest BRect which contains all of
|
||||
the points which describes the BPolygon.</P></LI>
|
||||
|
||||
<LI><P><B>Map To:</B> The MapTo() member function applies a translation (ie move) and a scale (ie
|
||||
grow/shrink) operation to the existing polygon, adjusting all points according to the passed in
|
||||
rule. The operation to apply depends on two passed in BRect's. The translation and scale
|
||||
adjustment which turns the first BRect into the second BRect is applied to all points in the
|
||||
BPolygon.</P></LI>
|
||||
|
||||
<LI><P><B>Print To Stream:</B> The PrintToStream() member function sends the set of points which
|
||||
make up the BPolygon to standard output. It does so by performing a PrintToStream() on the
|
||||
individual BPoint's which make up the polygon. This member is generally used for debugging and
|
||||
the output is primarily human readable and not sensitive to changes which could risk backward
|
||||
compatibility.</P></LI>
|
||||
|
||||
<LI><P><B>Assignment Operator</B> The operator=() operator is defined for BPolygon's. It takes
|
||||
a source BPolygon and assigns it to another existing BPolygon target. The state of the target
|
||||
BPolygon is lost and replaced with that of the source. The source retains its state so the outcome
|
||||
is two BPolygons with the same state (ie set of points).</P></LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BPolygon Implementation:</H2>
|
||||
|
||||
<P>Internally, the BPolygon contains an array of BPoint's which it uses to track the shape it
|
||||
holds. The implementation of BPolygon is fairly simple since it is a fairly basic container
|
||||
class for a set of points.</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
Reference in New Issue
Block a user