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

Vienna 3.0.6 :5eaf312: - RSS and Atom ne...
Vienna is a freeware and Open-Source RSS/Atom newsreader with article storage and management via a SQLite database, written in Objective-C and Cocoa, for the OS X operating system. It provides... Read more
Kodi 15.1.rc1 - Powerful media center to...
Kodi (was XBMC) is an award-winning free and open-source (GPL) software media player and entertainment hub that can be installed on Linux, OS X, Windows, iOS, and Android, featuring a 10-foot user... Read more
Bookends 12.5.8 - Reference management a...
Bookends is a full-featured bibliography/reference and information-management system for students and professionals. Access the power of Bookends directly from Mellel, Nisus Writer Pro, or MS Word (... Read more
Chromium 44.0.2403.125 - Fast and stable...
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web. Version 44.0.2403.125: This release contains a number... Read more
iMazing 1.2.2 - Complete iOS device mana...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
Audio Hijack 3.2.0 - Record and enhance...
Audio Hijack (was Audio Hijack Pro) drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio... Read more
FontExplorer X Pro 5.0.1 - Font manageme...
FontExplorer X Pro is optimized for professional use; it's the solution that gives you the power you need to manage all your fonts. Now you can more easily manage, activate and organize your... Read more
Calcbot 1.0.2 - Intelligent calculator a...
Calcbot is an intelligent calculator and unit converter for the rest of us. Featuring an easy-to-read history tape, expression view, intuitive conversion, and much more! Features History Tape -... Read more
MTR 5.0.0.1 - The Mac's oldest and...
MTR (was MacTheRipper)--the Mac's oldest and smartest DVD-backup app--is now updated to version 5.001 MTR -- the complete toolbox, not a one-trick, point-and-click extractor. MTR is intended for... Read more
LibreOffice 4.4.5.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

Card King: Dragon Wars - Tips, Tricks an...
[Read more] | Read more »
Pac-Man Championship Edition DX has brou...
Bandai Namco has released Pac-Man Championship Edition DX on iOS and Android, which features the classic arcade gameplay that we've all grown to love. Pac-Man Championship Edition DX can be enjoyed in much shorter bursts than the arcade versions... | Read more »
Cosmonautica (Games)
Cosmonautica 1.1 Device: iOS Universal Category: Games Price: $6.99, Version: 1.1 (iTunes) Description: Cast off! Are you ready for some hilarious adventures in outer space? | Read more »
Rescue humanity from a Demon horde in An...
Angel Stone is Fincon's follow up to the massively successful Hello Hero and is out now on iOS and Android. You play as a member of The Resistance, a group of mighty human warriors who have risen up in defiance of the Demon horde threatening to... | Read more »
Gallery Doctor (Photography)
Gallery Doctor 1.0 Device: iOS iPhone Category: Photography Price: $2.99, Version: 1.0 (iTunes) Description: Free up valuable iCloud and iPhone storage with Gallery Doctor, the only iPhone cleaner that automatically identifies the... | Read more »
You Against Me (Games)
You Against Me 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: A simple game… You. Me. Claim, steal, lock, score, win! | Read more »
Yep, it's True - Angry Birds 2 is O...
The not exactly rumors were true and the birds are back. Angry Birds 2 has come to the App Store and the world will... well I suppose it'll still be the same, but now we have more bird-flinging options! [Read more] | Read more »
You Could Design Your Own Card for Chain...
If you've ever wanted to create your own item, weapon, trap, or even monster for Chainsaw Warrior: Lords of the Night, this is your chance. Auroch Digital is currently holding a contest so that fans can fight to the death (not really) to see which... | Read more »
Bitcoin Billionaire is Going Back in Tim...
If you thought you managed to buy everything there is to buy in Bitcoin Billionaire and make all the money, well you though wrong. Those of you who made it far enough might remember investing in time travel - and it looks like that investment is... | Read more »
Domino Drop (Games)
Domino Drop 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Domino Drop is a delightful new puzzle game with dominos and gravity!Learn how to play it in a minute, master it day by day.Your... | Read more »

Price Scanner via MacPrices.net

Back-to-School with Tablet and Smartphone Acc...
Belkin helps you prepare for the coming school year with a wide variety of the latest mobile and tablet accessories to outfit both grade school and college students. The line-up includes charging... Read more
11-inch MacBook Airs on sale for $100 off MSR...
Best Buy has 11-inch MacBook Airs on sale for $100 off MSRP. Choose free shipping or free local store pickup (if available). Sale prices for online orders only, in-store prices may vary: - 11″ 1.6GHz... Read more
iPad Air 2 on sale for up to $100 off MSRP
Best Buy has iPad Air 2s on sale for up to $100 off MSRP on their online store for a limited time. Choose free shipping or free local store pickup (if available). Sale prices available for online... Read more
Sale! 13-inch MacBook Pros on sale for $100 o...
B&H Photo has 13″ MacBook Pros on sale for $100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.5GHz/500GB MacBook Pro: $999.99 save $100 - 13″ 2.7GHz/128GB Retina... Read more
Sale! Save $100 on 13-inch MacBook Airs this...
B&H Photo has the 13″ 1.6GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY tax only. Their price is $100 off MSRP, and it’s the lowest price available for this model.... Read more
Worldwide Tablet Market Decline Continues, Ap...
The worldwide tablet market declined -7.0% year-over-year in the second quarter of 2015 (2Q15) with shipments totaling 44.7 million units according to preliminary data from the International Data... Read more
TP-LINK TL-PA8030P KIT Powerline Featuring Ho...
Consumer and business networking products provider TP-LINK is now shipping its TL-PA8030P KIT AV1200 3-Port Gigabit Passthrough Powerline Starter Kit that expands your home’s network over its... Read more
Apple refurbished iPad Air 2s available for u...
The Apple Store has Apple Certified Refurbished iPad Air 2s available for up to $140 off the price of new models. Apple’s one-year warranty is included with each model, and shipping is free: - 128GB... Read more
Updated Apple iPad Price Trackers
We’ve updated our iPad Air Price Tracker and our iPad mini Price Tracker with the latest information on prices and availability from Apple and other resellers. Read more
Apple refurbished 2014 13-inch 128GB MacBook...
The Apple Store has Apple Certified Refurbished 2014 13″ MacBook Airs available starting at $759. An Apple one-year warranty is included with each MacBook, and shipping is free: - 13″ 1.4GHz/128GB... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Infrastructure Engineer - *Apple* /Mac - Hil...
Infrastructure Engineer - Apple /Mac Job Code: 1608 # of openings: 1 Description Our fortune 500 client is looking to hire an experienced Infrastructure Engineer to join Read more
Executive Administrative Assistant, *Apple*...
…supporting presentation development for senior leadership. * User experience with Apple hardware and software is preferred. Additional Requirements The following list Read more
*Apple* Bus Company is now hirin - Apple Bus...
Apple Bus Company is now hiring school bus drivers in the Pettis County area. Class B CDL preferred. Free training provided. No nights or weekends required. Flexible Read more
*Apple* Certified Mac Technician - Updated 6...
…and friendly, hands-on technical support to customers troubleshooting and repairing Apple /Mac products with courtesy, speed and skill. Use your problem-solving skills Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.