Be Newsletter
Issue 55, January 8, 1997
Table of Contents
BE EVENTS: Be at Macworld Expo 97 and at UC Davis
- The Be Booth at Macworld
Look for an arch with a rather large "Be" on it in the south
hall. We'll be in booth number 1649, giving demos and
showing off software from a number of developers.
- The Power Computing Booth at Macworld
Check out the BeOS at the Power Computing booth. We'll be
there talking about Power's license of the BeOS, and we'll
be showing off the BeOS on Power's new machine, the...
we'll, you'll have to wait a bit longer for that. Power will
be in the north hall, booth 4380. Look for a very big video
wall...
- Be Demo Tour starts again. We'll show off the BeBox at UC
Davis, CA.
BeBox General Demo Meeting
Sponsored by UCD Bookstore and the UCDMUG
Wednesday, January 15, 1997, 5:30 pm
126 Wellman Hall
(Wellman Hall is between Wickson and Hart on West Quad
Street.)
BE ENGINEERING INSIGHTS: In Case You Missed It
By Peter Potrebic
Our latest release, DR8, should be in everyone's hands by
now. What I'd like to do is point out a few of the subtler
changes in DR8 that might otherwise get overlooked. As a
developer myself, I know that it's easy to get accustomed to
a certain feature set and API, overlooking new and
potentially better APIs.
The first change I'd like to discuss deals with view
attributes and how they're handled in the BeOS. By view
attribute I mean all the various graphical attributes of a
view, including high color, low color, pen size, and font.
I'd bet that anyone who's ever written a graphical Be
application has overridden the BView::AttachedToWindow
method in order to set the value of some view attribute.
While it might seem natural to initialize these attributes
in the view constructor, in releases prior to DR8 this was
not possible because a connection to the Application Server
was required, and this connection doesn't exist until the
view is attached to a window. More than one of you have
politely suggested that we could improve our system by
eliminating this restriction. We always try to listen and in
this case we did: In DR8 I removed this restriction. Now you
can set the attributes of a view at any time, even before
the view is added to a window.
I'm pointing this out because many folks have probably
become accustomed to overriding AttachedToWindow() , so they
continue doing so even if there's a simpler way. Breaking
that habit ought to make it even easier to program the BeOS.
Just set whatever attribute you want in the view
constructor. In DR9, as a further improvement, I added a
cache for all the attributes. Previously calls like Bounds()
and HighColor() required a call to the Application Server.
With the cache in place the Application Server isn't needed,
so these getter functions are much faster. This means that
you don't have to worry about calling too many getters
inside of an update, and you don't have to implement your
own caching, the system does it for you.
Another new feature in DR8 that I'd like to point out is
keyboard navigation. Here at Be we love the mouse, but we
also love the keyboard. We've always supported the idea of
allowing complete control of the machine via the keyboard,
without sacrificing ease of use via the mouse. I might add
that a rather influential person at Be has long been the
biggest proponent of keyboard navigation (his title is CEO).
Menu bars have been navigable via the keyboard from day one,
but it took until DR8 to extend this functionality to
include controls. New in DR8 is the ability to navigate the
controls in a panel from the keyboard. Here are the basic
rules of this UI:
For more information on keyboard navigation, and on getting
your own custom control working in this system take a look
at the Interface Kit chapter of The Be Book, pages 234-235.
In DR9 keyboard navigation will be extended to include the
notion of groups of controls. With this new feature you'll
be able to jump from group to group simply by pressing
Control-Tab. This will make it easier to navigate a complex
panel with lots of controls. The API for creating a group of
controls is very simple. I didn't want to force developers
to redo how you're laying out panels, so adding this
functionality had to be simple. All you do to create a group
is to set the B_NAVIGATE_JUMP flag in the appropriate view.
If your group of controls has a common parent view (like a
BBox), then simply set the JUMP flag in that parent view.
The BBox class defaults to having that flag set. If your
group of controls doesn't have a unique parent, then set the
JUMP flag in the first control in the group. It's that
simple.
I hope this helps you take advantage of some of the new
features of DR8 and the upcoming DR9 release.
BE ENGINEERING INSIGHTS: BTW, Did We Mention That...
By Don Larkin
Perhaps the most vexing API changes are those that don't
present any outward signs of a change: A function has the
same name as before, it takes the same set of arguments, and
its return type is the same -- but it now works somewhat
differently than it did in previous releases. We try to keep
such changes to a minimum and to highlight them for you when
they occur. But because they don't show on the surface, they
sometimes slip by unnoticed, even inside Be. Vigilant
readers of The Be Book will note that we were slow to catch
the fact that in DR8 a 0 timeout meant 0 microseconds, not
an infinite period as it did in DR7. Or that the drawing
code you invoke between BeginPicture() and EndPicture() no
longer is rendered on-screen as the picture is recorded.
One subtle change that went unreported for DR8 affects the
run-time type information (RTTI) macros found in the Support
Kit. The macros let a program discover type information from
an unknown object -- say an object stored in a BList or
retrieved from a received BMessage , or more generally any
object (such as the current focus view) returned by a
function and typed to a base class. You'd typically use the
macros to find whether the object can be typed to a more
specific class. The Support Kit currently defines four RTTI
macros:
class_name(object) returns the name of the object's class.
is_instance_of(object, class) returns TRUE if the object
is a direct instance of the target class, and FALSE if not.
is_kind_of(object, class) returns TRUE if the object is an
instance of or inherits from the target class, and FALSE if
not.
cast_as(object, class) returns the object cast to the
target class if it's safe to do so, and NULL if not.
Originally, these macros rested on a class-information
system invented by Peter Potrebic and implemented as part of
the BeOS. That system was abandoned in DR8 in favor of the
RTTI system that's now part of the C++ language and
supported by the Metrowerks compiler. The macros didn't
change, but the new implementation subtly altered the
behavior of two of them -- is_kind_of() and cast_as() .
The original RTTI system supported two styles of programming
with these macros. You could use the cast_as() macro to cast
a retrieved object to a target type:
void MyHandler::MessageReceived(BMessage *msg)
{
MyView *mv;
. . .
case WHATEVER:
mv = cast_as(msg->FindObject("source"), MyView);
if ( mv )
mv->DoWhatMyViewsDo();
break;
. . .
}
or you could arbitrarily cast the object to a target type
and then use the is_kind_of() macro to see if the cast was
correct:
void MyHandler::MessageReceived(BMessage *msg)
{
MyView *mv;
. . .
case WHATEVER:
mv = (MyView *)msg->FindObject("source");
if ( mv && is_kind_of(mv, MyView) )
mv->DoWhatMyViewsDo();
break;
. . .
}
This second style is no longer supported and, in fact,
should no longer be considered good programming practice.
The general rule is that the declared type of an object must
_always_ be accurate; an object should be typed only to its
own class or to a class that it inherits from. If the
declared type isn't accurate, as it may not be when
is_kind_of() is called in the code above, the RTTI macros
can't be trusted to rescue the situation. In the above
example, is_kind_of() will always return TRUE, no matter
what the "source" object really is.
In their new guises, both cast_as() and is_kind_of() are
based on the C++ dynamic_cast() operator and they reflect
its behavior. To talk about its behavior without getting too
tongue-tied, let's adopt the following shorthand terms for
an object's type:
- The "real" type of an object is its type on construction.
For example, if you construct an instance of the
BButton
class, BButton is its real type.
- The "declared" type of an object is the type label it
currently bears. For example, if you get a
BButton object
from a function that returns a BView (such as BWindow's
FocusView() function), BView will be its declared type at
that point in the program.
- The "target" type of an object is the type you want to
cast it as or test it against.
In the old implementation, the RTTI macros compared the
target type only to the object's real type. However, the
dynamic_cast() operator considers the real type only if it
has to. It first compares the target type to the object's
declared type. It assumes that the declared type is accurate
(that the object is truly the kind of object it's
represented to be) and it summarily handles the obvious
cases: If the target type is the same as the declared type
or if it's a class that the declared type inherits from, the
operation will succeed. Consequently, cast_as() will cast
the object to the target type and is_kind_of() will return
TRUE, regardless of the object's real type.
In other words, if the target class is above or at the same
level as the declared class in the inheritance hierarchy,
the real class is ignored. However, you would rarely want to
cast an object to a more general type. Typically, you'd want
to discover whether it can be cast to a type that's more
specific than the declared type. For that, it's necessary to
look at the object's real type.
dynamic_cast() considers the real type of the object only if
the declared type doesn't match or derive from the target
type. It then makes the same sort of comparison between the
target and real types that it first attempted between the
target and declared types. If the target type is identical
to the real type, or if it's a class that the real type
derives from, the operation succeeds. If not, it fails.
The dynamic_cast() operator and, by extension, the
is_kind_of() and cast_as() macros, will produce reliable
results as long as objects are not arbitrarily cast to types
that may not be accurate. Despite this restriction,
is_kind_of() remains a useful macro. Use it in a way that
mirrors how cast_as() works -- to check the type of an
object _before_ casting it, not afterwards. For example:
void MyHandler::MessageReceived(BMessage *msg)
{
BObject *obj;
. . .
case WHATEVER:
obj = msg->FindObject("source");
if ( obj && is_kind_of(obj, MyView) )
((MyView *)obj)->DoWhatMyViewsDo();
break;
. . .
}
In contrast, the behavior of the class_name() and
is_instance_of() macros hasn't changed. They're now based on
the C++ typeid() operator, which ignores the declared type
of the object and always looks at the real type.
Will the RTTI macros be adjusted again in the future?
Probably not. But if a change is made, we'll try to catch it
and report it to you at the time.
BE DEVELOPER TALK: Steve Sprang
E-mail: sprang@andrew.cmu.edu
I first became interested in computers when I was in sixth
grade. My father had just purchased a Macintosh Plus, and I
spent much of my spare time creating wondrous graphics in
SuperPaint and throwing rocks at buzzards in Dark Castle.
Although I'd been playing with computers since I was six
years old -- first a Timex Sinclair 1000 and then a
Commodore 64 -- it was the Plus that showed me what exciting
machines computers can be.
Today I'm a computer science major and a Be developer. For
me, the BeOS has brought back the thrill of discovering
computers all over again. My BeBox has been a source of many
an "Oh" and "Ah" since I received it last May. A couple of
days after Christmas I received my "BeOS for Power
Macintosh" CD. My Power Mac 8500, which I'd neglected since
I got my BeBox, has found a new place in my heart. Needless
to say, I'm very interested in seeing multiple 604s in one
machine.
So far, I've released four BeOS applications. First, there
was BeTetris; this was my "get to know the OS" project, but
I think it turned out pretty well. Then came AudioDancer,
which doesn't seem to work on the Power Macintosh. And
lastly, two little demos, Langston's Ant and a slightly-
more-advanced-than-Be's QuickCam viewer.
Over winter break I started work on a morphing application,
called Metamorph. I need to refine the interface and
increase the speed, but you can expect to see a beta release
before the end of January. I'm also planning to write a
Prolog interpreter. I don't expect there to be a huge demand
for such a beast, but I'm personally interested in
implementing a language from scratch, and I grew quite fond
of Prolog in one of my courses last semester.
Programming for the BeOS has been unbelievably easy. I threw
together the core interface for Metamorph in just a few
hours. This included loading JPEG images and a drag-and-drop
interface for reordering morph sequences. Don't even get me
started on how easy it is to implement scroll bars. I almost
feel guilty... almost. As a full-time student with limited
free time, I really appreciate the ease with which I can
turn an idea into a working program.
Well, there you have a brief run-down of my little corner in
the Be world.
Programs I have developed for BeOS can be found at:
http://www.andrew.cmu.edu/user/sprang/besoft.html
Oh yeah, if I don't get that Be internship I'm hoping for, I
wouldn't mind interning for a third-party that "just"
develops Be applications. ;)
News from the Front
By William Adams
At its best, computing on the bleeding edge is akin to a
religious experience. At its worst, it can leave you
disoriented, panting, and disappointed. The bleeding edge is
sought by those with a passion to push the limits in the
pursuit of performance that can't be found in the
mainstream. Both the hacker fringe as well as the unafraid
end users seek the bleeding edge as a competitive advantage.
To ride the bleeding edge takes patience, perseverance, and
a very thick skin. The end result for the developer is that
the bleeding edge turns into the leading edge, and they now
have a market into which they can sell a product. The
bleeding edge doesn't stay sharp forever. If the bleeding
edge doesn't become the leading edge, then it has simply
become an also-ran. Not a fertile market for the
distribution of new fresh products, but simply a carcass of
technologies to be picked at by the rest of the scavengers
in the industry. The leading edge too can suffer a similar
fate. If it doesn't continue innovation, the leading edge
also becomes the backwater of technologies that were.
When I was a youngin, I managed a computer store. This was
at a time when the Macintosh was bleeding-edge, innovative
technology. I helped host the first Mac Fest at UC Berkeley
and sold many thousands of these little mono boxes. People
loved them. Compared to the PC of the time, they were
bleeding edge, innovative, easy to use, and just plain cute.
History is now showing us that the Macintosh and its OS have
transitioned from bleeding edge to leading edge, spawning
quite a healthy industry around it. The platform has become
so successful that there is now a burgeoning clone hardware
market. This market is screaming for something that's
bleeding edge to show it off.
Several of the Mac clone manufacturers are working on
multiprocessor machines with 2 and 4 processors. These are
real screamers! As the rest of the mainstream market chases
the ever-elusive fastest single CPU, these machines are
going to leap from them in performance. At least that's what
they hope. The problem is, they don't have the right OS to
make them really sing. The MacOS, which they're supposed to
be supporting, was never designed for these monsters of
computing prowess. These dual and quad megamachines resemble
those cute 9" mono Macs as much as man resembles an amoeba.
But they're expected to run off the same fuel.
Enter the BeOS. Symmetrical multiprocessing, multithreaded,
multi... The BeOS was born for this environment. Be has not
produced any machines to date that don't have more than one
processor. We can truly say that the BeOS was designed, and
more importantly, tested in real usage on multiprocessor
machines. The impact of this design and its computational
value are just now becoming clearly understood and utilized.
After I did my stint as a computer reseller, I chased a
dream to follow the NeXT big thing. I became a NeXTStep
developer and followed the rise and fall of yet another
bleeding-edge technology. But it never quite panned out. We
had some commercial success, but the market just never
materialized. This particular bleeding edge didn't quite
garner enough popular support, so it didn't make it to the
leading edge phase.
The next stop was Taligent. Another bleeding edge, except it
sure had a lot of padding! In hindsight I think they just
had too much money and not a big enough mandate to ship a
product, nor a reasonable platform upon which to ship it.
Waiting for Copland and running on AIX just were not good
choices. I was able to file a couple of patents for
collaborative technologies though, and that can't be all
bad.
I feel much more comfortable with the BeOS than with any of
the other bleeding-edge platforms of the near past. The
company is small. The product is good and growing better all
the time. License agreements are in place that will ensure a
ready market for developer's wares. And from what I've seen
of the new crop of Mac clones, our developers are going to
have quite a fertile ground upon which to place their most
compute-intensive dream applications. Seeing a well-crafted,
multithreaded, interactive 3D walk-through environment
running on dual PowerPC 604s at 225 MHz simply makes the
mouth water. And no, you can't do this at home with the
MacOS!
It's the beginning of the year and I'm waxing poetic about
my own past and what I see in the future of my newfound
love. I joined Be because the OS kicks and the BeBox rocks.
Seeing all the new hardware coming through our doors makes
me happier all the time that I made the decision to leave
some fading-edge technologies and once again ride the
bleeding rail. I hope all our developers will feel the same
when they bring their apps up on the new crop of hardware.
The experience is nothing short of amazing, and your
immediate reaction will be to start burning brain cells
trying to figure out what you're going to do with all that
newfound power.
See you at Macworld.
Enterprise vs. Multimedia
By Jean-Louis Gassée
In one respect, NeXT has always played a part in Be's life.
When we started the company, many sages questioned our
viability: Look at NeXT, they've spent hundreds of millions
of dollars and couldn't give critical mass to their
platform. And now that NeXT is tucked under Apple's wing,
the question is updated: How can you survive against the
combination of NeXT technology and Apple's market presence?
Let's first address Apple's decision to pick NeXT over Be
for the foundation of its future OS. When Apple approached
us in June 1996 with a request to look at the BeOS, it
became obvious we leveraged Apple's rich heritage of
creative media applications. NeXT, on the other hand, had
scored points in the marketplace with enterprise-wide,
networked, mission-critical, custom-programmed applications.
Picking NeXT is an enterprise play for Apple. Compared to
NeXT and their more mature product, at this early stage of
our life our platform and our company have little to offer
in the enterprise market against Windows NT, Sun, or
Hewlett-Packard. Our company was founded to address a very
different domain: The computing demands of digital media
content creators.
We respect Apple's decision and we thank them for having
considered the BeOS.
Now what do we do? We continue with our work: Building up
the BeOS platform, working with developers and with business
partners such as Metrowerks and Power Computing. Half a
dozen ex-NeXT employees work at Be. With their help, we've
gone back and re-analyzed NEXTSTEP. It is indeed a stable,
polished platform, based on UNIX and Display PostScript,
with proven custom programming and, more recently, Web
tools. Its UNIX and Display Postscript heritage limit its
performance in the kind of high-bandwidth, interactive,
media-rich applications that are the BeOS' sweet spot.
Furthermore, as is typical with workstation operating
systems, its performance is less attractive on entry-level
PC configurations.
In summary, we have a less mature but more modern, more
agile platform; we do well in creative multimedia
applications, while Apple's new OS is aimed at the
enterprise market.
And we continue to add value to Power Mac hardware, and to
the PowerPC in general.
Amateurs of trivia might want to reread the columns I wrote
for NeXTWorld and MacWeek
(http://www.macweek.com/mw_1049/op_capsule.html). And, going
back to the beginning of this column, for us, NeXT
eloquently demonstrates that persistence pays off.
BeDevTalk Summary
BeDevTalk is an unmoderated discussion group that's a forum
for the exchange of technical information, suggestions,
questions, mythology, and suspicions. In this column, we
summarize some of the active threads, listed by their
subject lines as they appear, verbatim, in the group.
To subscribe to BeDevTalk, visit the mailing list page on
our Web site: http://www.be.com/aboutbe/mailinglists.html.
- -----WEEK 3---------------------------
Subject: Accessing Preferences
A "preferences server," which would allow distributed access
to a user's settings, was proposed and discussed. Also of
interest was the discussion of an application registry
architecture: When you install an application, how should
the system note the new app's existence?
At a slightly lower level, the "granularity" of preference
items was debated. One listener suggested that preferences
should be class-based. In other words, each C++ class
(BApplication among them) could have its own set of
preferences.
- -----NEW---------------------------
Subject: BeOs on a PowerBook 5300?
AKA: Powerbook BeOS must happen
Is a port to the PowerBook crucial? Some folks think it
would fill a gaping hole in the Be product line; others feel
that Be should wait for a more stable (and more surely
supported) portable. Perhaps, it has been suggested, Be
should build its own.
- -----NEW---------------------------
Subject: Remote Displays
Regarding remote displays: How difficult would it be (for
Be) to allow messages to be sent to Application Servers that
are running on remote machines? To what extent will the
interface API, which assumes a single, set-in-stone
Application Server, have to be altered to allow the identity
of the server to change as an app is running (and,
potentially, being passed between machines)? Conversely,
should remote machines only be used for display (that is,
the local Application Server sends data to a remote display,
rather than the local "connection object" sending ops to a
remote Application Server). What mechanism should be used to
deliver environment info to the (remote) machine that will
be launching an app (or "receiving" a running app)?
The discussion slid into a request for a good multi-user
action game.
- -----NEW---------------------------
Subject: Suggestion: Dictionary/Spell checker database
How about using the database to store a dictionary, thus
making spell-checking apps (and the like) easy to write and
eminently extensible? Theoretically sound, but it might
require too much disk space (120 MB for a 250,000-word
dictionary, by one estimate).
So instead, how about a dictionary server that could run
over the network? (No objections.)
- -----NEW---------------------------
Subject: Apple, NeXT, Be
Although this thread started out as a rumor mill/soap box,
it offered some technical debate over the merits of
Objective-C (Next) and C++ (everybody else). Some of the
observations:
- Objective-C isn't a solution to the fragile base class
problem (as is sometimes claimed); it works for methods
(member functions) but doesn't protect the instance
variables (data members).
- Objective-C's everything-is-virtual attitude makes for
poor function call performance (it was claimed). However,
pointers to Objective-C methods, which are initially looked
up by name, are cached so that performance improves as the
cache "warms up."
- Sending a BeOS C++
BMessage (and waiting for a response)
is much slower than calling an Objective-C method. But (it
was countered), is this a valid comparison?
|