TweetFollow Us on Twitter

What Is PowerPlant

Volume Number: 14 (1998)
Issue Number: 12
Column Tag: PowerPlant Workshop

What Is PowerPlant?

by John C. Daub, Austin, Texas, USA

An introduction to and overview of the Metrowerks PowerPlant application framework

Introduction

Despite what many have said, I just don't see it. The Mac programming community doesn't seem to be dying (like many naysayers suggested last year). People are still flocking to the Mac (especially after the iMac introduction), and I still see newcomers every day in the comp.sys.mac.oop.powerplant USENET newsgroup - all with a burning desire to write the next "KillerApp." Many of the next generation programmers want to use Metrowerks PowerPlant to accomplish their goal, but quickly run into the same problem. PowerPlant is enormous, and can be intimidating - where and how do you start? I have heard this complaint from many aspiring PowerPlant users, and I can't blame them.

To try and help programmers become more familiar with PowerPlant, I decided to write a series of articles that will introduce various parts of the PowerPlant architecture to MacTech readers. These topics should be interesting to both new and experienced programmers. I know few people that understand all of PowerPlant (or even a large chunk), so I think there will be something for everyone.

This article will start with the very basics. We'll introduce frameworks in general, and then PowerPlant in specific. We'll talk about the advantages of using PowerPlant, and then describe the overall design of PowerPlant. We'll look into how event's are handled in PowerPlant, and how information is communicated between different parts of PowerPlant. You may see some simliarities to the first few chapters of the PowerPlant Book, Metrowerks' official documentation for PowerPlant - a book I highly recommend. In later articles, we'll get more "hands-on" and demostrate some of the real power of PowerPlant. But first, let's start with the basics.

Background

Definition

What is PowerPlant? The easy answer is: PowerPlant is Metrowerks Corporation's object-oriented application framework for Mac OS software development. It is written in the C++ programming language, and takes full advantage of the features C++ offers (such as multiple inheritance, polymorphism, templates, and namespaces). PowerPlant provides programmers with a collection of solid, field-tested, code that can serve as a mature foundation upon which to build your software product - letting you build more reliable applications, in less time.

Not only does PowerPlant help you lay a rock-solid foundation for your application, but PowerPlant also provides a wealth of tools beyond what you would expect from a simple application framework. For example, there are TCP/IP networking classes; debugging classes to help write better code; classes that simplify threading and extend the capabilities of the Thread Manager; and classes for all the major Internet protocol implementations (POP3, SMTP, FTP, HTTP, Finger, NTP, IRC). PowerPlant offers flexible implementations of and support for Mac OS technologies like Drag and Drop, the Appearance Manager, and the Contextual Menu Manager. PowerPlant includes cool things like Attachments, that world-class Metrowerks Technical Support, and will comply with and support Carbon as Carbon develops and evolves. That's just the short list.

Pretty neat, huh? That list makes it seem like PowerPlant can do a lot. But there are a lot of buzzwords and technical jargon in it that might not be familiar to you. Let's break this definition into smaller pieces and examine each piece in turn.

PowerPlant Prerequisites

PowerPlant assumes two fundamental skills: you need to be able to use the C++ programming language and be able to use the Mac OS Toolbox.

PowerPlant is written in the ANSI/ISO C++ programming language. Earlier I mentioned some wonderful C++ language features: namespace, template, polymorphism, and multiple inheritance. You don't need to know anything about them. They're certainly powerful features and if you're curious you might consider buying a copy of the recently drafted ANSI/ISO C++ standard for those tough questions that will occasionally arise. You do need to be able to write basic C++, and you'll need to know how to use inheritence explore PowerPlant. But that's about it. Beginners are certainly welcome here, and you will assuredly sharpen your C++ skills as you work with the language.

PowerPlant simplifies and hides some of the OS-level details from you. For instance, the Networking Classes unify the two TCP/IP mechanisms (MacTCP and Open Transport) into a single API (Application Programmer's Interface) for TCP/IP communication. Because you only have to talk to the single interface (PowerPlants interface), you can write less code while still offering your application to many different kinds of users. However, you can't always work from this higher level of abstraction. At times you will have to get some dirt under your fingernails and dig into the Toolbox directly. This doesn't mean you have to be an expert on the Toolbox, just make sure you understand the basics of how the Mac OS works and how to work with the Toolbox when you need to. There is a lot of documentation and sample code out there to help you, as well as a very open, welcoming, and helpful community of other Mac OS developers on forums such as the comp.sys.mac.programmer.* newsgroup hierarchy.

If you need some help becoming familiar with C++ or understanding how the Mac OS Toolbox works, there are lots of good books at your local bookstore, or perhaps your local library. If you can lay a good foundation for yourself, it will be a lot easier further down the road to work with the framework.

So What is a Framework?

PowerPlant is a framework... but what is a framework? Before we can answer that question, we need to provide some background and discuss code reuse and the various types of reusable code.

It takes time to run a business, time is money, and a business needs and wants to make money. If something could be done to make more and expend less, typically a business would find this "thing" a positive means. Many typical software development tasks have already been done by some party somewhere. Fortunately many authors of these codes are willing to make their solutions available for others to use; some as commercial ventures, others as free and open source. These codes are developed over the course of many months and/or years, which enables them to be field tested, reliable, focused, and most importantly, (re)usable. If it took these parties months or years to develop these codes into mature products, how long would it take you to reinvent the wheel? And does that provide the best cost-benefit ratio for your company? Depending upon your situation perhaps it might - each and every situation must be evaluated on its own merits under its unique circumstances. But chances are better that the reuse of code will provide the bigger payoff. You might want to read § 23.5.1 of Bjarne Stroustrup's The C++ Programming Language (3rd edition). As the creator of C++, Stroustrup raises some interesting issues about code reuse. Besides, you need to beat your competition to market, and reusable code could give you that advantage. Reusable code is no panacea (what is?), but it can be a Good Thing.

There are various types of reusable code. There are the random examples and snippets that can be found in places like collection CD's (Apprentice) and websites (Apple, alt.sources.mac). Although these examples and snippets tend to be unorganized and random (at least compared to other types of reusable code), nonetheless they can be quite useful at solving specific problems that can arise during the course of development.

A procedural code library is a more ordered collection of reusable code snippets, routines, and/or utilities. The ANSI C Standard Library is an example of this type of reusable code. It contains routines for string manipulations (strcpy, strlen), file i/o (fopen, fwrite), mathematics (sin, cos, log), and sundry utilities (rand, qsort), amongst other things. Libraries, such as the C Standard Library, are very useful indeed. However, as procedural code libraries tend to try to provide a higher degree of reuse by addressing the lowest common denominator, they tend to be more generic and of a utility nature than some other types of reusable code, such as class libraries.

A class library provides a similar sort of utility as a procedural code library, but it also attempts to provide greater flexibility than a procedural library. A class library achieves this by virtue of being written in an object-oriented language, such as C++ or Java. The ANSI C++ Standard Library is an example of this type of reusable code. It provides strings (string), i/o (iostream, fstream), numerics (valarray, complex), and sundry utilities (typeinfo, vector), just like the Standard C Library does (which, by the way, is actually a subset within the C++ Standard Library). But these portions of the C++ Standard Library provide greater flexibility to you through use of C++ templates. "Templates provide a simple way to represent a wide range of general concepts and simple ways to combine them. The resulting classes and functions can match hand-written more-specialized code in run-time and space efficiency. Templates provide direct support for generic programming." (Stroustrup 1997). So you can see how a class library can have benefits over a procedural code library, but at least compared to a framework, a class library remains fairly generic.

A framework is a structured collection of routines (functions, methods, procedures), typically written in an object-oriented language, designed for reuse to aid in the solving of a specific software development problem. Of the various types of reusable code, it tends to be more specific in nature, aimed towards the solving of a particular problem set. In PowerPlant's case, this would be aiding in the development of software for the Mac OS. In terms of reusable code, the PowerPlant framework might not be as extensible as a more generic class library (e.g. PowerPlant does not target Unix very well), but because PowerPlant has a more directed focus (i.e. software for Mac OS), the job that it does it does well.

To clarify a bit more, PowerPlant is actually an application framework. Frameworks aim to solve specific problems, such as database solutions, multimedia packages, games, and so forth. An application framework is designed to aid in the authoring of applications. The framework provides some core structure (LEventDispatcher, LCommander, LBroadcaster); means for tapping into, and extending or even limiting that structure (LAttachment, LPeriodical); interface tools (LPane, LMenu), and useful utilities (UMemoryMgr, StDialogHandler). What a framework lacks is the unique content that makes an application your application - no need to spend time, money, nor brain power on anything but the specifics of your Killer App.

Of course with all good there is some bad. PowerPlant, as specific as the above might make it sound, is still somewhat generic. It attempts to address the needs of the majority of its users - not everyone will find exactly what they need immediately available in PowerPlant (sometimes called the "80/20 Rule", or "you cannot please everyone"). To work within these constraints, PowerPlant attempts to provide as much flexibility as possible to the user so that you can construct your own custom solution. We will discuss some of the designs in the next section.

As an application framework, PowerPlant offers a great deal. It provides you with a solid foundation. It provides you with basic as well as advanced tools to make your code more efficient and more robust, while saving you development time and resources. Just how it can provide these savings is the subject of the next section.

PowerPlant Design Patterns

At first, PowerPlant seems like a huge folder with hundreds of files and thousands upon thousands of lines of code - how can anyone make sense of this? Where do you start? Thankfully, PowerPlant is very well organized and designed; all you need is a roadmap to help you find your way through the various design patterns that PowerPlant employs. As you travel down the road, these basic patterns should begin to make sense to you. As you begin to understand the basic patterns, look for how the patterns work together to form the framework and provide to you the benefits mentioned above. The concepts we will discuss here are: event handling, targets and command chain, visual interface, interobject communication, persistence, and utilities.

Event Handling

Mac OS applications utilize an event-driven programming model. This model puts the application user in control, and the actions of the user drive the application. There are a known set of possible events, such as mouse clicks and keystrokes. When one of these events occur, the operating system (Event Manager) notifies your application of the event and provides important information about the event. For example, when you click the mouse, the Event Manager will provide your application with the coordinates of where the mouse was when the click occurred. When your application receives this information, it must respond appropriately (show a menu, display the typed character, etc.).

Because event handling and dispatch is an essential part of any Mac OS application, it is a perfect candidate for a framework. PowerPlant provides this core event handling through the LEventDispatcher class. LEventDispatcher has methods to dispatch and handle each event type appropriately. The class also provides for typical event-related behaviors such as adjusting the look of the cursor and performing menu updates.

LEventDispatcher only knows how to start the event down a specific event path. If the application user presses a key on their keyboard, LEventDispatcher starts the ball rolling to process that keystroke, but it does not process the keystroke itself. Suppose you had numerous text fields in your application's window? How does LEventDispatcher know which text field to direct the keystroke towards? Enter the concept of targets and command chains.

Targets and Command Chain

When you select a command from a menu or press a key on the keyboard, this event is dispatched to the target for handling. A target is the object to which most (if not all) directed events are dispatched . There is at most one target at any time. The target also helps to determine the state of the applications' menus. For example, if an editable text field (LEditField) was the current target and there was text on the clipboard that could be pasted into the field, the Paste menu item would be enabled. If the LEditField contained a selection, the Cut, Copy, and Clear commands would be enabled as well. If the target changed to an LEditField that could not be edited, the Edit menu (and its items) would be disabled to reflect the field's read-only status. As commands are target-oriented, it is only logical that menu state is influenced by the target.

If the target is unable to process the given command, the command is passed to the next object in the command chain to see if it can process the command. A command chain is a list, or more typically a tree, of commanders. A commander is a object that can respond to a command. Within the chain of command, a commander can have subcommanders but has only one supercommander (except for the top-most commander, which has no supercommander). Depending where a commander falls in the command chain, it could be both a subcommander (to another supercommander) and a supercommander (to other subcommanders).

All of this command work is handled by PowerPlant's LCommander class. It handles command chain maintenance (adding, modifying, removing) and target management (switching, being, not being). An object that wishes to handle commands mixes in the LCommander class, and typically will override the FindCommandStatus() and ObeyCommand() methods. FindCommandStatus() is utilized by LEventDispatcher to determine the menu state, and ObeyCommand() performs the actual command handling.

As mentioned before, if the object cannot handle a command, the object passes the command to the next commander in the command chain. In PowerPlant the target is usually at the end of one of the command chain branches. If the target cannot handle the command, it passes the command to its supercommander to see if it could handle the command. If this object cannot handle the command, the command is passed to the object's supercommander. This is repeated until some object handles the command, or we have reached the end/top of the chain.

The bottom-up approach to the command chain has some advantages over the top-down approach. First, this provides objects the ability to stand alone. The object only has to specify and handle commands that are relevant to itself, and then can pass all others to its supercommander (whatever that might be). There is no need to repatch the commander chain when you wish to add a new object into the chain, plus this aids in furthering good object-oriented design. Second, since the command chain is a tree, it is much easier to walk up the chain than down. Each commander has at most one supercommander, so there is only one path to the top.

Commanders are a very important part of PowerPlant. They are the main avenue by which the users' actions are dispatched and executed. LCommander provides a simple, yet powerful, means for the processing and management of commands and commanders. Since LCommander is provided as a mix-in class, any object that wants or needs to respond to user commands can do so. This use of multiple inheritance in PowerPlant enables those visual elements, like LEditField, to respond to user actions (furthering that event-driven programming model), and those elements that do not need to directly respond to user actions, like LCaption, remain as simple and streamlined as possible.

Visual Interface

One of the main goals of an application framework is to provide tools for creating and managing the application's interface. There are a multitude of tasks involved here including: creation of interface objects, establishing the proper drawing environment, actual rendering of the element on screen, managing coordinate schemes, and managing an object's relation to other objects in terms of location and appearance. Perhaps the most prominent feature of PowerPlant is the tools that it provides for management of the visual interface. These tools include Constructor, LPane and friends, and a host of utilities.

Figure 1. Metrowerks Constructor.

Constructor is the visual interface design and layout tool for PowerPlant (Figure 1). With Constructor you are able to design your screens in a WYSIWYG fashion. You can establish your windows and dialogs, their content, and the properties and behaviors of all of these elements. Constructor saves this layout information in a 'PPob' resource, which is a complex data structure that describes your screens. This data is then read and interpreted by PowerPlant to reanimate your screens at runtime (see UReanimator). And although Constructor is not a general-purpose resource editor like ResEdit or Resorcerer, it does allow you to edit PowerPlant resources ('Txtr', 'Mcmd'), some additional Mac OS resource types ('MENU', 'MBAR', 'STR#'), and bitmap resources (cursors, icons, PICTs, and patterns). We will take a more in-depth look at Constructor in a future article.

The basic class for all visual objects in PowerPlant is LPane. By itself, an LPane does not do much, but it does provide the basic form and function for all visual objects. In addition to the responsibilities mentioned at the beginning of this section, LPane also provides mechanisms for handling mouse clicks, obtaining the value and/or descriptor for an object (if such an attribute is relevant), coordination between the PowerPlant and Mac OS coordinate schemes, mouse tracking and cursor adjustment, and printing.

One behavior LPane does not have is the ability to manage subpanes in the visual hierarchy. Some interface objects do not need nor desire this ability, so why bloat those objects with additional and unnecessary code? For those objects that do need or want subpanes, there is LView. LView inherits from LPane, and essentially is a pane that can contain other panes. LView takes on most of the work involved in managing a pane's geographical relationship to other panes, and also provides support for scrolling a pane. Using LPane or LView as a base, you can create any interface object you might need; in fact, PowerPlant offers many common widgets: windows (LWindow), dialog boxes (LDialogBox), checkboxes (LCheckBox), radio buttons (LRadioButton), push buttons (LPushButton), popup menus (LPopupButton), scrollbars and scroller views (LScroller), text fields (LEditText, LTextEditView), sundry Appearance Manager controls (LProgressBar, LBevelButton) and so forth. And as you can see, PowerPlant's naming conventions try to be straightforward and logical. Readability of code is an important design principle in PowerPlant.

There is another design principle that permeates all of PowerPlant that is worth discussing here. This principle is factoring, which means that larger, more complex behaviors should be broken down into smaller, component parts. We have already discussed some of PowerPlant's factoring, such as the use of mix-in classes and multiple inheritance (LCommander, LEventDispatcher), and the relationship of LPane and LView. Hopefully these prior discussions have adequately demonstrated the benefits of a factored design.

An additional factored behavior used by PowerPlant is separating actions into a setup part and the actual action part. The setup part establishes any necessary states before the action executes. This could include state testing and modification, ensuring certain elements exist, and restoring states after the action has completed. The action part performs the actual activity. If setup proceeds with no problems, the setup then initiates the action. To perform the entire action, you call the setup method; usually you will not call the action method directly as performing the action without proper setup could lead to problems. In PowerPlant, the setup is performed by a function with the same name as the function (e.g. Draw(), Click(), Show()). LPane::Draw() is shown in Listing 1.

Listing 1: LPane's Draw Function

LPane::Draw

void
LPane::Draw( RgnHandle   inSuperDrawRgnH )
{
   Rect      frame;
   if ( (mVisible == triState_On) &&
       CalcPortFrameRect(frame) &&
       ((inSuperDrawRgnH == nil) ||
       ::RectInRgn(&frame, inSuperDrawRgnH)) &&
       FocusDraw() ) {
       
      PortToLocalPoint(topLeft(frame));   
      PortToLocalPoint(botRight(frame));
      
      if (ExecuteAttachments(msg_DrawOrPrint, &frame)) {
         DrawSelf();
      }
   }
}

Draw() performs the generic setup actions that must be performed before any object draws itself. It ensures the object is visible, is within QuickDraw space, intersects the inSuperDrawRgnH, and can be focused. If all of these criteria are met, then and only then will it proceed to actually draw the object. The action, drawing the object in this case, is performed in a function named the same as its associated setup function with the word "Self" appended (e.g. DrawSelf(), ClickSelf(), ShowSelf()). Since LPane's implementation of DrawSelf() is empty, here is LCaption::DrawSelf(). LCaption is a subclass of LPane that draws a string of text.

Listing 2: LPane's Draw Function

LCaption::DrawSelf

void
LCaption::DrawSelf()
{
   Rect   frame;
   CalcLocalFrameRect(frame);
   
   SInt16   just = UTextTraits::SetPortTextTraits(mTxtrID);
   
   RGBColor   textColor;
   ::GetForeColor(&textColor);
   
   ApplyForeAndBackColors();
   ::RGBForeColor(&textColor);
   
   UTextDrawing::DrawWithJustification(
                  (Ptr)&mText[1], mText[0], frame, just, true);
}

Due to the factored "Self" design, LCaption::DrawSelf() (listing oes not need to worry about general drawing setups - this is handled by LPane::Draw(), which LCaption inherits. LCaption only needs to trouble itself to establish its specific drawing needs (setting the text traits and fore/back colors) and then perform the core action of drawing the text string. To actually draw the string, just call the Draw() method:

// obtain a pointer to the LCaption object

LCaption *theCaption = dynamic_cast<LCaption*>
             (theWindow->FindPaneByID(kCaptionID));

// draw the caption

theCaption->Draw(nil);

Most subclasses of LPane only need to override the DrawSelf() method to implement their specific drawing needs, leaving the housekeeping details to the framework. The same applies for other "Self" situations (override ClickSelf() and call Click() in response to a mouse click, override FinishCreateSelf() and call FinishCreate() to finish creating an PowerPlant visual object/element).

The final visual interface tool that we will address are interface utilities. We will discuss these utilities later in the article.

Interobject Communication

The commander mechanism is a specialized communication channel: it only communicates vertically through the commander chain, only at event processing time, and only carries messages about and allows responses to commands. While this form of interobject communication is vital to an application's existence, it is too specialized for general use. So instead, PowerPlant offers a broadcaster-listener mechanism for interobject communication.

A broadcaster is an object that sends a message when a certain behavior occurs, like when a button is clicked. A broadcaster can broadcast multiple messages and/or multiple message types depending upon context. To make an object a broadcaster in PowerPlant, you only need to utilize the LBroadcaster mix-in class (once again, factored design) and specify where and what to broadcast. As an example, here's a fictitious button object that broadcasts when it is clicked:

Listing 3: ClickSelf for CMyButton

CMyButton::ClickSelf

void
CMyButton::ClickSelf(const SMouseDownEvent &inMouseDown )
{
   // the button has been clicked, notify the world
   BroadcastMessage( msg_ButtonClicked, nil);
}

A listener is an object that listens for one or more messages. When a desired message is "heard" the listener will react accordingly, perhaps beeping in response to the button click. A listener does not have to react to every message that it might receive. To make an object a listener in PowerPlant, mix in the LListener class and implement the ListenToMessage() function. Here's a fictitious listener object that is listening to the fictitious CMyButton object and beeps in response to the button being clicked:

Listing 4: ListenToMessage

CSomeObject::ListenToMessage

void
CSomeObject::ListenToMessage(
   MessageT      inMessage,
   void            *ioParam )
{
   // we are listening to CMyButton
   if ( inMessage == msg_ButtonClicked ) {
      ::SysBeep(3);
   }
}

The benefit of this factored design is that the broadcasters and listeners can remain independent of each other. The broadcasters do not need nor care to know who is listening or how they may react to the message. The listeners of course do need to know about particular messages, but they not need nor care to know about the broadcaster itself. This independence allows listeners to be added or removed at any time, for there to be any number of broadcasters or listeners (including none), and for improved object-oriented design.

Persistence

No, this does not refer to human perseverance, but rather to the need for data to exist across volatile states, such as the application launching and quitting or turning the computer on and off. This is the intent of storage media, like a hard drive or Zip disk, and the folders (to organize) and the files (to actually store the data) on that media.

The LFile class represents a basic Mac OS file (including support for both the data and resource forks) and provides the low-level means for manipulating the file and its forks (open, close, read, write, etc.). The higher-level means of file manipulation (save, save as, revert, print, etc.) are provided through the LDocument class. LDocument is an abstract class which associates one or more windows with one or more files, and also provides a means to manipulate the document (save, print, etc.) via AppleEvents. LSingleDoc is provided to give you a concrete instantiation of LDocument that actually connects an LFile to an LWindow.

If you are familiar with the C++ Standard Library, then you are probably familiar with the concept and benefits of streams (an ordered series of bytes of data). If not, to avoid a lengthy discussion here just know that streams help to transfer data from one place (file, keyboard, screen, printer) to another (file, keyboard, screen, printer). PowerPlant provides an abstract LStream class that has all the features and functions any stream class would need: marker manipulation, reading and writing data, and overloaded redirection operators to make working with various data types easier. Other provided classes are: LFileStream, for streaming data to/from a file's data fork; LDataStream, for pointer-based data; LHandleStream, for Handle-based data; and LDebugStream, for streaming information to a debugger.

Utilities

Although the main purpose of a framework is to provide a cohesive and integrated set of tools, there are always sundry tasks and chores involved in application writing. PowerPlant offers many utility classes to aid in the handling of mundane chores, keeping your code error and exception safe, and extend or even modify the behavior of your interface with a quasi-plugin architecture. It would be impossible to describe all of PowerPlant's utility features within the scope of this article, so instead here is a brief overview of some of the highlights:

LClipboard
Manages the Clipboard.
LGrowZone
A GrowZone implementation for managing low-memory situations.
LPeriodical
A mechanism for calling a function on a regular basis.
LSharable
A base class for a reference counted object.
LString
A base class for handling Pascal-style strings.
UDebugging
Basic debugging support.
UDrawingState
Classes for saving/restoring the drawingstate.
UDrawingUtils
Useful utilities for drawing (device loops, drawing text, marching ants).
UMemoryMgr
Classes for management of memory.
UProfiler
Aid for application profiling.
URegions
Facilitates working with Regions.
UTextTraits
Manages the appearance of text in UI objects.

This list is far from exhaustive; in fact many of the listed classes, like UDrawingState and UMemoryMgr, are actually files that group logical utility classes into a central location (there is no UDrawingState class, but the UDrawingState.cp file defines classes such as UQDGlobals, StGrafPortSaver, and StColorState). Take a read through the source code files and see what is offered. There is a great deal of exploration you can do and a great deal you can learn as well by reading the PowerPlant source code. And that is another benefit of PowerPlant! Full source is provided on the CodeWarrior CD.

One area of the utility classes that I find particularly neat are the stack-based classes (these are classes that begin with "St"). The C++ language has a powerful hook: the destructor. Whenever a stack-based object goes out of scope, the destructor for that object will be called. The bonus here is that if an object exits scope normally or abnormally, say from an exception being thrown, the destructor for that object is still called. So by exploiting this hook, you can work to automate cleanup. The technique is simple: the constructor performs an action (saves a state, allocates memory, etc.) and the destructor performs the converse (restores the state, frees the memory, etc.). To illustrate this, let us look at PowerPlant's StDeleter template class. StDeleter , like the C++ Standard Library's auto_ptr, manages a pointer allocated via new. The StDeleter constructor takes ownership of the pointer, and the destructor calls delete upon it.

If you did not use StDeleter, your code might look like this:

Listing 5: Stacks without using StDeleter

{
   Foo   *theFoo = new Foo;
   Bar *theBar = nil;
   
   try {
      theBar = new Bar;
   } catch (...) {
      // Creation of theBar failed. Clean up to
      // avoid memory leaks.
      delete theFoo;

      // rethrow the exception
      throw;
   }
   
   try {
      theFoo->MightThrowAnException();
   } catch (...) {
      // Again, must clean up to avoid memory leaks
      delete theFoo;
      delete theBar;
      
      // rethrow
      throw;
   }
   
   delete theFoo;
   delete theBar;
}

As you can see, it is quite cumbersome to contend with the possibility for an exception to be thrown. We have to use numerous try/catch blocks to perform cleanups in case an exception is thrown. But if we use StDeleter to manage the objects, the code can look like this:

Listing 6: The same code as listing 5, using StDeleter

{
   StDeleter<Foo>   theFoo( new Foo );
   StDeleter<Bar>   theBar( new Bar );
   
   theFoo->MightThrowAnException();
}

To quote Porky Pig, "That's all folks." The design of the two code examples is the same (allocate 2 objects, call a function, avoid memory leaks, clean up after yourself), but the implementations are quite different. In this second case, if an exception is thrown when allocating theBar, theFoo's destructor is called and its memory is released. Remember, in this second example, theFoo is an StDeleter<Foo> object, not a Foo* object as it was in the first example. So when StDeleter's destructor is called, it deletes its internal pointer to the Foo* object, and all is well. If MightThrowAnException() does throw and exception, the destructors for theFoo and theBar are called and the memory is released. And if all goes without problem and we reach the end of the function, the objects leave scope normally and memory is released. Stack-based classes are not unique to PowerPlant, but PowerPlant does take advantage of this feature of the C++ language to enable you to write more robust and exception-safe code.

Conclusion

If you have made it this far, I hope that you're getting excited about PowerPlant. I have only begun to touch on the features, power, and potential of PowerPlant. There are still actions, for Undo support; AppleEvent support, to make your application fully scriptable and recordable; classes for displaying tabular data; Array classes for managing dynamic lists of data; and the list continues.

If you have questions about PowerPlant, please feel free to send me email or visit the comp.sys.mac.oop.powerplant newsgroup. Also, you might want to pull out a copy of the PowerPlant Book. Give a read through the first few chapters, maybe delve into later chapters and try your hand at PowerPlant coding. The next article will give you a more hands-on introduction to PowerPlant, and really show you what PowerPlant can do. Additionally, if you have any questions, comments, criticisms, or other feedback about this article or the article series, please do not hesitate to drop me a line.

Bibliography, References, and URLs


John C. Daub is currently one of Metrowerks' PowerPlant Engineers. Since he joined Metrowerks in 1996 he has been involved with PowerPlant in some capacity or other, from technical support to quality assurance to authoring. If you have questions about PowerPlant, or if you have any good lawn care tips (especially if you're familiar with Texas soils) you can contact John at hsoi@metrowerks.com.

John would like to thank Dave Mark for encourging him to write this article, Carl, Richard, Kenny, and the PowerPlant user community for input and ideas, and also thank Greg and Vicki for kicking him when he needed it. He especially want's to thank his wife, Michele for believing in him, and his son, Wade, for making him get off the computer once in a while to watch Toy Story (again :-).

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

PushPal 3.0 - Mirror Android notificatio...
PushPal is a client for Pushbullet, which automatically shows you all of your phone's notifications right on your computer. This means you can see who's calling or read text messages even if your... Read more
Logic Pro X 10.1.1 - Music creation and...
Apple Logic Pro X is the most advanced version of Logic ever. Sophisticated new tools for professional songwriting, editing, and mixing are built around a modern interface that's designed to get... Read more
VLC Media Player 2.2.0 - Popular multime...
VLC Media Player is a highly portable multimedia player for various audio and video formats (MPEG-1, MPEG-2, MPEG-4, DivX, MP3, OGG, ...) as well as DVDs, VCDs, and various streaming protocols. It... Read more
Sound Studio 4.7.8 - Robust audio record...
Sound Studio lets you easily record and professionally edit audio on your Mac. Easily rip vinyls and digitize cassette tapes, or record lectures and voice memos. Prepare for live shows with live... Read more
LibreOffice 4.4.1.2 - Free, open-source...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
Freeway Pro 7.0.3 - Drag-and-drop Web de...
Freeway Pro lets you build websites with speed and precision... without writing a line of code! With its user-oriented drag-and-drop interface, Freeway Pro helps you piece together the website of... Read more
Cloud 3.3.0 - File sharing from your men...
Cloud is simple file sharing for the Mac. Drag a file from your Mac to the CloudApp icon in the menubar and we take care of the rest. A link to the file will automatically be copied to your clipboard... Read more
Cyberduck 4.6.5 - FTP and SFTP browser....
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Firefox 36.0 - Fast, safe Web browser. (...
Firefox for Mac offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals and... Read more
Thunderbird 31.5.0 - Email client from M...
As of July 2012, Thunderbird has transitioned to a new governance model, with new features being developed by the broader free software and open source community, and security fixes and improvements... Read more

Get The Whole Story – Lone Wolf Complete...
Get The Whole Story – Lone Wolf Complete is Now Available and On Sale Posted by Jessica Fisher on February 27th, 2015 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Who Wore it Best? The Counting Dead vs....
Like it or not, the “clicker” genre, popularized by cute distractions like Candy Box and Cookie Clicker, seems like it’s here to stay. So Who Wore it Best? takes a look at two recent examples: The Counting Dead and AdVenture Capitalist. | Read more »
Card Crawl, the Mini Deck Building Game,...
Card Crawl, the Mini Deck Building Game, is Coming Soon Posted by Jessica Fisher on February 27th, 2015 [ permalink ] Tinytouchtales and Mexer have announced their new game, | Read more »
Witness an all new puzzle mechanic in Bl...
Well, BlastBall MAX is not one of those games and is bucking trends such as timers, elements of randomness, and tacked-on mechanics in favor of pure puzzle gameplay. When you first boot up the game you’ll see a grid made up of squares that are each... | Read more »
This Princess Has a Dragon and She isn’t...
This Princess Has a Dragon and She isn’t Afraid to Useit. | Read more »
Mecha Showdown Review
Mecha Showdown Review By Lee Hamlet on February 27th, 2015 Our Rating: :: IN A SPINUniversal App - Designed for iPhone and iPad Mecha Showdown replaces traditional buttons with a slot machine mechanic in this robot fighting game,... | Read more »
Reliance Games and Dreamworks Unveil Rea...
Reliance Games and Dreamworks Unveil Real Steel Champions Posted by Ellis Spice on February 27th, 2015 [ permalink ] Reliance Games and Dreamworks have announced that a third game in | Read more »
Sum Idea Review
Sum Idea Review By Jennifer Allen on February 27th, 2015 Our Rating: :: TAXING NUMBERSUniversal App - Designed for iPhone and iPad Sum Idea is a fairly charming but taxing puzzle game.   | Read more »
A New Badland Update Brings Daydream Lev...
A New Badland Update Brings Daydream Levels to Co-Op Posted by Ellis Spice on February 27th, 2015 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Slashing Demons Review
Slashing Demons Review By Lee Hamlet on February 27th, 2015 Our Rating: :: IT'S A LONG WAY TO THE TOPUniversal App - Designed for iPhone and iPad Slashing Demons lacks the depth or scope to take it beyond the point of being just... | Read more »

Price Scanner via MacPrices.net

Apple Launches Free Web-Based Pages and Other...
Apple’s new Web-only access to iWork productivity apps is a free level of iCloud service available to anyone, including people who don’t own or use Apple devices. The service includes access to Apple... Read more
Survey Reveals Solid State Disk (SSD) Technol...
In a recent SSD technology use survey, Kroll Ontrack, a firm specializing in data recovery, found that while nearly 90 percent of respondents leverage the performance and reliability benefits of SSD... Read more
Save up to $600 with Apple refurbished Mac Pr...
The Apple Store is offering Apple Certified Refurbished Mac Pros for up to $600 off the cost of new models. An Apple one-year warranty is included with each Mac Pro, and shipping is free. The... Read more
Updated Mac Price Trackers
We’ve updated our Mac Price Trackers with the latest information on prices, bundles, and availability on systems from Apple’s authorized internet/catalog resellers: - 15″ MacBook Pros - 13″ MacBook... Read more
Apple CEO Tim Cook to Deliver 2015 George Was...
Apple CEO Tim Cook will deliver the George Washington University’s Commencement address to GWU grads on May 17, at which time he will also be awarded an honorary doctorate of public service from the... Read more
Apple restocks refurbished Mac minis for up t...
The Apple Store has restocked Apple Certified Refurbished 2014 Mac minis, with models available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: - 1.4GHz... Read more
Save up to $50 on iPad Air 2s, NY tax only, f...
 B&H Photo has iPad Air 2s on sale for $50 off MSRP including free shipping plus NY sales tax only: - 16GB iPad Air 2 WiFi: $469.99 $30 off - 64GB iPad Air 2 WiFi: $549 $50 off - 128GB iPad Air 2... Read more
16GB iPad Air 2 on sale for $447, save $52
Walmart has the 16GB iPad Air 2 WiFi on sale for $446.99 on their online store for a limited time. Choose free shipping or free local store pickup (if available). Sale price for online orders only,... Read more
iMacs on sale for up to $205 off MSRP
B&H Photo has 21″ and 27″ iMacs on sale for up to $205 off MSRP including free shipping plus NY sales tax only: - 21″ 1.4GHz iMac: $1029 $70 off - 21″ 2.7GHz iMac: $1199 $100 off - 21″ 2.9GHz... Read more
Apple Takes 89 Percent Share of Global Smartp...
According to the latest research from Strategy Analytics, global smartphone operating profit reached US$21 billion in Q4 2014. The Android operating system captured a record-low 11 percent global... Read more

Jobs Board

Sr. Technical Services Consultant, *Apple*...
**Job Summary** Apple Professional Services (APS) has an opening for a senior technical position that contributes to Apple 's efforts for strategic and transactional Read more
Event Director, *Apple* Retail Marketing -...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global engagement strategy and team. Delivering an overarching brand Read more
*Apple* Pay - Site Reliability Engineer - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.