TweetFollow Us on Twitter

Modifying Objects At Runtime

Volume Number: 15 (1999)
Issue Number: 3
Column Tag: PowerPlant Workshop

Modifying Objects at Runtime in PowerPlant

By John C. Daub, Austin, Texas USA

A look at PowerPlant's Attachments mechanism

Welcome!

One of the things that makes the Mac so great and so much fun to use is the ability to customize your Mac just the way you like it. There are all sorts of cool functional utilities like Monaco Tuner/ProFont and FinderPop, and many cosmetic enhancers like the ubiquitous Kaleidoscope. Just how do these cool tools do the voodoo that they do so well? Through the magic of trap patching! Patching traps is a neat way to change the runtime behavior of an application and/or the OS itself without having to actually change the application or OS. Think of it like subclassing to implement new functionality for an object, but you didn't have to subclass to actually gain the new functionality - something else came in at runtime and modified the object's behavior.

If that explanation only served to further confuse you, I apologize. However, by the end of this article you will have a better understanding of the statement. You see, PowerPlant has a mechanism akin to patching called Attachments. Attachments are a way to modify the runtime behavior of PowerPlant objects, so in a sense it can be viewed as patching. By using PowerPlant's Attachments mechanism you can extend, limit, or otherwise change the behavior of a PowerPlant object at runtime, and all through a mechanism that's simple yet very powerful; in fact the theory of the Attachments mechanism will play a larger role throughout PowerPlant in future versions of the framework.

By the way, if you're curious about trap patching, check out a book like Dave Mark's Ultimate Mac Programming. Dave recruited Jorg Brown to write the chapter on trap patching, so you'll definitely be in good hands.

Overview

PowerPlant's Attachment mechanism is comprised of two parts: the Attachment's host and the Attachment itself.

Attachables

An object that can host Attachments is called an Attachable. The LAttachable class defines an Attachable object, and any class that inherits from LAttachable can have Attachments attached to it (you cannot attach Attachments to objects that are not Attachables). Within PowerPlant, LAttachable is used as a virtual base class for some key base objects: LCommander, LEventDispatcher, and LPane (see my introduction to PowerPlant article in the December 1998 MacTech or refer to the PowerPlant Book, Metrowerks' official documentation on PowerPlant, for an explanation of these classes)


Figure 1. LAttachable class hierarchy.

Although Figure 1 does not look like much, do not forget the great number of classes that inherit from LCommander and LEventDispatcher, and especially the multitude of classes that inherit from LPane (there was just no way to print such a large hierarchy within the constraints of this article). Since these key objects are Attachables, you can begin to see that many of PowerPlant's key behaviors can be modified through the use of Attachments.

The LAttachable class provides all the functionality a host needs to manage Attachments. One can AddAttachment() or RemoveAttachment() to add or remove Attachments from the Attachable's internal list of Attachments. If you're in a hurry, you can call RemoveAllAttachments() to remove all of an Attachable's Attachments. Accessors are provided to GetDefaultAttachable() and SetDefaultAttachable() (the default Attachable is the object to which an Attachment will be attached when it is created from a PPob DataStream). Finally LAttachable provides ExecuteAttachments() as the ever-important means to allow Attachments to carry out their task. Most of your interactions with LAttachable will be through AddAttachment() (and possibly RemoveAttachment()), as the rest is handled for you within PowerPlant itself. Of course the other part of the equation here are the Attachments themselves, so let's take a look at them.

Attachments

An Attachment is an object that can modify the runtime behavior of another object without having to modify that object itself. Through the use of Attachments, you can modify how an object: handles events, draws or prints, handles clicks and keypresses, adjusts the cursor, responds to commands and actions, and even how it finishes creating itself. Figure 2 presents the Attachment classes provided by PowerPlant.


Figure 2. LAttachment class hierarchy.

The points at which the Attachments are given the opportunity to modify the runtime behavior of its host object (i.e. the places within PowerPlant where LAttachable::ExecuteAttachments() is called) are well defined by the PowerPlant API. Since the intent of an Attachment is to modify the "normal" behavior of an object, this Attachment execution point occurs immediately before the host object executes its normal course of action. So just before that mouse click is given to the Pane object for processing, the Pane's Attachments are given first crack at the click. Listing 1 illustrates how this looks in code.

Listing 1: Attachment execution point

LPane::Click()
void
LPane::Click(
   SMouseDownEvent&      inMouseDown)
{
   if (!inMouseDown.delaySelect) {
   
      PortToLocalPoint(inMouseDown.whereLocal);
      
      UpdateClickCount(inMouseDown);
      
      if (ExecuteAttachments(msg_Click, &inMouseDown)) {
         ClickSelf(inMouseDown);
      }
   }
}

When Click() is called, a little housekeeping is performed, then just before the actual handling of the click is to occur (ClickSelf()), the Pane's Attachments execute and could veto the execution of the Pane's normal click functionality. We'll look at how all of this works in the next section.

Like the LAttachable class, the LAttachment class is also quite simple. It contains constructors and a destructor, as one would expect of a C++ class. One item to note is LAttachment has an LStream constructor, which means that Attachment objects, like Pane objects, can be constructed from a PPob DataStream. You can edit Attachments in Constructor, they have class_ID's, and must be registered (see URegistrar) if you create your Attachments in this manner. If you've worked with Panes in PPob's, this procedure should be familiar to you. If you're not familiar with this procedure, it is covered in the PowerPlant Book.

There are three data members in LAttachment: mOwnerHost, mMessage, and mExecuteHost (and all three have associated Get/Set accessor methods). The first data member, mOwnerHost, is a pointer to the Attachment's host object for easy reference. The mMessage data member stores the particular message that the Attachment is to respond to. Finally, the mExecuteHost member is a Boolean value which specifies if the host should continue to execute its normal course of action or not. In the next section you'll see how these data members come into play.

The remaining two methods in LAttachment are Execute() and ExecuteSelf(). This is where all of the action happens, so to better explain them let's take a look at just how the Attachment mechanism actually works.

How Does It Work?

As you saw in the previous sections, the LAttachable and LAttachment classes are fairly simple, and the mechanisms by which they are implemented and execute are fairly simple as well. As mentioned previously, an Attachable iterates its list of Attachments at a well-defined point asking them to execute and passing them any relevant information the Attachment may need in order to properly execute in the given context. Figure 3 summarizes those points within PowerPlant.


Figure 3. Attachment execution points.

When in the course of an application's events it becomes necessary to execute an Attachment (the Where Called column in Figure 3), the host iterates its list of Attachments asking each if it cares to do something relevant to the given situation; this is done by calling the Attachment's Execute() method. Within Execute() the Attachment checks the message given to it by its host; if that message is the same as the Attachment's mMessage (or is the special msg_AnyMessage), then Attachment then calls its ExecuteSelf() to do its voodoo. Within ExecuteSelf() the Attachment of course does whatever it does (respond to the click, handle the event, modify the host's cosmetics, etc.), but also must specify if upon returning the host should continue to execute its normal action or not by calling SetExecuteHost(). If the Attachment wishes to completely override the host's behavior, the Attachment should SetExecuteHost(false). If the Attachment wishes to merely augment the behavior, SetExecuteHost(true). Note this only affects the execution of the host action; if the host has other Attachments that have not yet executed, they will still execute.

That's all there is to how the Attachment mechanism works! It is such a simple mechanism, but so much can be accomplished through it. If you still don't believe me, there is an example application on the CodeWarrior Reference CD (the Attacher demo, part of the PP Mini Demos) and I've written a sampler to accompany this article as well (which should be on the MacTech web/ftp site). The Attacher demo shows how the mechanics of Attachments work, and my demo can show you all of the things you can do with Attachments.

Working With Attachments

Now that you understand how Attachments work, I'm sure you want to start to actually work with Attachments. Just as the mechanism itself is fairly simple, working with Attachments isn't very difficult either. The two primary areas in which you will work with Attachments is how to add/use them within your own projects, and how to create your own Attachments.

Adding Attachments

There are two ways to add an Attachment to an Attachable: on the fly or through a PPob. To add an Attachment on the fly you first create the Attachment via its "parameterized" constructor, then add it to a host by calling the host's AddAttachment() method. Listing 2 illustrates adding an LClipboard Attachment to your Application object (CApplication represents your Application object subclass, and remember that LApplication inherits from LCommander, which inherits from LAttachable).

Listing 2: Adding an Attachment on the fly

CApplication::Initialize()
void
CApplication::Initialize()
{
      // Create the LClipboard Attachment
   LClipboard*   theClipAttachment = new LClipboard;

      // Attach it to our Application object
   AddAttachment(theClipAttachment);
}

Although some Attachments, like LClipboard must be created and added on the fly as above, other Attachments can be created from a PPob DataStream (many Attachments support both creation mechanisms). Just like you can edit the Panes in your PPob's within Constructor for that wonderful WYSIWYG experience, you can add and edit some Attachments in Constructor as well.


Figure 4. Editing Attachments in Constructor.

As mentioned previously, to create your Attachment via the PPob DataStream, the Attachment must have an LStream constructor and a class_ID, just like Panes that you create from the PPob DataStream. As well, you must register your Attachment with URegistrar so the reanimation process will work correctly (again, for more information on PowerPlant's reanimation and registration mechanisms, consult the PowerPlant Book). If you create your Attachments in your PPob's, the Attachment is attached to whatever object it is hierarchically beneath. In Figure 4, the LWindowThemeAttachment will be attached to the LWindow; the LBeepAttachment is attached to the LStaticText. This is where the default attachable comes into play. Take a look at LAttachment's LStream constructor and the routines in UReanimator to see exactly how the default attachable is used.

In addition to editing Attachments in PPob's, you can also edit the CTYP information for the Attachment's themselves. By creating your own CTYP's for your Constructor objects, they'll appear in the Catalog window and can facilitate working in Constructor. Figure 5 shows the Constructor CTYP editor. Of course you can find more information on creating CTYP's and using Constructor in the Constructor Manual, Metrowerks documentation for Constructor.


Figure 5. Editing Attachment CTYP's in Constructor.

Creating your own Attachments

With what I've shown you so far, I hope you've been able to see just how simple it is to work with Attachments. But if there is anything difficult about Attachments it might be writing your own Attachment classes. The process itself isn't difficult - it's the first step of finding the behavior to implement that might throw you off a bit. Before you begin to write the Attachment you must design it well. You must decide what behavior you wish to implement, and then how it will fit into the Attachment mechanism: what message(s) to respond to; if the host should execute or not, and then under what circumstances to execute or not; if the Attachment can be created from a PPob DataStream; etc.

As soon as you have your design and goal(s) for the Attachment set, the implementation process is fairly short and simple. You need to have at least one constructor that allows the Attachment to be created on the fly. If the Attachment can be created from a PPob DataStream you must provide an LStream constructor and class_ID. Then implement your ExecuteSelf() to do the Attachment's magic, and you're done! In the implementation of ExecuteSelf(), be aware to SetExecuteHost() as needed. And if you wish to add that finishing touch, create a CTYP file for your Attachment so it can be easily edited within Constructor.

Take a look at the Attachments that PowerPlant provides, such as those in UAttachments.cp. There isn't much to their implementation, but as you use Attachments more and more you'll find yourself appreciating that simplicity. Conversely, if you look at my HCmdButtonAttachment (which is part of the demo application that accompanies this article), you'll see that Attachments aren't always lightweight, but the power they can bring makes them a great tool to have in your toolchest.

Why Use Attachments?

If you've made it this far, I hope that you've been able to gain an understanding of what Attachments are and just how they work within PowerPlant. You've seen the LAttachable and LAttachment classes, how the Attachments mechanism works, and how to build your own Attachments. But there is one question that remains: why would you use Attachments?

Remember that Attachments modify the runtime state and/or behavior of their host object. By being able to add to, remove from, or otherwise modify how an object behaves, you can do some nifty stuff and have a lot of code to reuse to boot. For example, a common feature in Mac applications today is the ability to simulate a mouse click on a button in a dialog with a keystroke; for instance, cmd-D could simulate a click on the "Don't Save" button in a "Save Changes" dialog. If you wanted to implement this behavior in a button class, you would subclass your main button class and implement the functionality to support the keystroke-as-click behavior. You did this for your PushButton class, but now you want the same functionality in your BevelButton class, so you have to reimplement the same code all over again. Then you want to have it in your CheckBox class, then your RadioButton class, and then you realize you want it in so many of your classes that it would be better to place it into a common parent class, but then this would break PowerPlant's existing inheritance chains so you would have to reimplement every single button widget you used... and you give up because this is getting ridiculous.

Consider the Attachment. You are implementing a behavior: handle a keystroke as if it was a click on a button (or any control for that matter). You create an Attachment that can intercept msg_KeyPress's, and whose ExecuteSelf(), upon receiving the correct keystroke calls SimulateHotSpotClick(), and you've now clicked the button without ever putting your hands on your mouse. Furthermore you've factored this behavior into stand-alone and reusable code. You can easily add this Attachment to your PushButtons, your BevelButtons, your RadioButtons, CheckBoxes, and any other Control you might desire. All the same code, no need to repeat nor reimplement the code, and no need to subclass anything - you can use stock objects. This is essentially what all Attachments do, and slightly more specific to this example, what the HCmdButtonAttachment Attachment does.

Attachments are also good for implementing new behaviors for legacy code. PowerPlant's Debugging Classes are centered around a menu that is added to your application's menubar and provides functionality to help debug and stress-test your application (see the Factory Floor column in the November, 1998 issue of MacTech for an overview of the Debugging Classes). Because the menu is implemented as an Attachment (LDebugMenuAttachment) it makes it quite simple to add and remove this functionality from an existing application. Furthermore, it enables you to have the Debug menu only in the debug builds of your application and not in your release builds. The modularity and "drop-in" capabilities of Attachments is another strength.

Conclusion

I hope you've been able to see what Attachments have to offer you as you continue you work with PowerPlant. If you have not used Attachments, do try the two demo applications and read over the various Attachment classes' source code; give them a try in your own applications. Most of the PowerPlant code that I've written recently has been Attachment based (e.g. LCMAttachment, LDebugMenuAttachment, HURLAttachment), and I find it to be one of the niftier and more flexible mechanisms that PowerPlant has to offer. After you're more familiar with Attachments, I'm sure you'll also find a place for them in your toolbox. What you can do with Attachments is pretty limitless, and after you write your first Attachment class I'm sure you'll agree with me.

Until next time... Happy programming!

Bibliography

  • Mark, Dave. Ultimate Mac Programming. Programmers Press, A Division of IDG Books Worldwide, Inc., Foster City, California. 1994.
  • Metrowerks Corporation. Constructor Manual. 1998.
  • Metrowerks Corporation. PowerPlant Book. 1998.
  • Metrowerks Corporation. PowerPlant Reference. 1998.
  • Monaco Tuner and ProFont: ftp://members.aol.com/squeegee/.
  • FinderPop: http://www.finderpop.com/.
  • Kaleidoscope: http://www.kaleidoscope.net/.

John C. Daub is one of Metrowerks Corporation's PowerPlant engineers. John wonders if you really care to know quirky biographical information about him, and if so, why? If you really want to know strange things about John or wish to ask him any questions (about PowerPlant or otherwise), you can reach John via email at hsoi@metrowerks.com.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

iFFmpeg 6.4.3 - Convert multimedia files...
iFFmpeg is a comprehensive media tool to convert movie, audio and media files between formats. The FFmpeg command line instructions can be very hard to master/understand, so iFFmpeg does all the hard... Read more
Alfred 3.4.1 - Quick launcher for apps a...
Alfred is an award-winning productivity application for OS X. Alfred saves you time when you search for files online or on your Mac. Be more productive with hotkeys, keywords, and file actions at... Read more
SyncTwoFolders 2.2.4 - Syncs two user-sp...
SyncTwoFolders simply synchronizes two folders. It supports synchronization across mounted network drives and it is a possibility to run a simulation showing in a log what will be done. Please visit... Read more
Maintenance 2.2.7 - System maintenance u...
Maintenance is a system maintenance and cleaning utility. It allows you to run miscellaneous tasks of system maintenance: Check the status of the hard disk Repair permissions Run periodic scripts... Read more
Hopper Disassembler 4.2.13- - Binary dis...
Hopper Disassembler is a binary disassembler, decompiler, and debugger for 32- and 64-bit executables. It will let you disassemble any binary you want, and provide you all the information about its... Read more
NeoOffice 2017 - Mac-tailored, OpenOffic...
NeoOffice is a complete office suite for OS X. With NeoOffice, users can view, edit, and save OpenOffice documents, PDF files, and most Microsoft Word, Excel, and PowerPoint documents. NeoOffice 3.x... Read more
Firefox 55.0.2 - Fast, safe Web browser.
Firefox 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 casual... Read more
Alfred 3.4.1 - Quick launcher for apps a...
Alfred is an award-winning productivity application for OS X. Alfred saves you time when you search for files online or on your Mac. Be more productive with hotkeys, keywords, and file actions at... Read more
Maintenance 2.2.7 - System maintenance u...
Maintenance is a system maintenance and cleaning utility. It allows you to run miscellaneous tasks of system maintenance: Check the status of the hard disk Repair permissions Run periodic scripts... Read more
NeoOffice 2017 - Mac-tailored, OpenOffic...
NeoOffice is a complete office suite for OS X. With NeoOffice, users can view, edit, and save OpenOffice documents, PDF files, and most Microsoft Word, Excel, and PowerPoint documents. NeoOffice 3.x... Read more

War Wings beginner's guide - how to...
War Wings is the newest project from well-established game maker Miniclip. It's a World War II aerial dogfighting game with loads of different airplane models to unlock and battle. The game offers plenty of single player and multiplayer action. We... | Read more »
How to win every 2v2 battle in Clash Roy...
2v2 is coming back to Clash Royale in a big way. Although it's only been available for temporary periods of time, 2v2 has seen a hugely positive fan response, with players clamoring for more team-based gameplay. Soon we'll get yet another taste of... | Read more »
Roll to Win with Game of Dice’s new upda...
Joycity’s hit Game of Dice gets a big new update this week, introducing new maps, mechanics, and even costumes. The update sets players loose on an exciting new map, The Cursed Tower, that allows folks to use special Runes mid-match. If you feel... | Read more »
Bottom of the 9th (Games)
Bottom of the 9th 1.0.1 Device: iOS iPhone Category: Games Price: $4.99, Version: 1.0.1 (iTunes) Description: Play the most exciting moment of baseball in this fast-paced dice and card game! | Read more »
The best apps for viewing the solar ecli...
If you somehow missed the news, many parts of the United States will be witness to a total solar eclipse on August 21 for the first time in over 90 years. It'll be possible to see the eclipse in at least some capacity throughout the continental U... | Read more »
The 5 best mobile survival games
Games like ARK: Survival Evolved and Conan Exiles have taken the world of gaming by storm. The market is now flooded with hardcore survival games that send players off into the game's world with nothing but maybe the clothes on their back. Never... | Read more »
Portal Walk (Games)
Portal Walk 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Portal Walk is adventure and relaxing platform game about Eugene. Eugene stuck between worlds and trying to find way back home.... | Read more »
Technobabylon (Games)
Technobabylon 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: City of Newton, 2087. Genetic engineering is the norm, the addictive Trance has replaced almost any need for human interaction,... | Read more »
5 reasons why 2v2 is the best mode in Cl...
Supercell has been teasing fans with 2v2 windows that allow players to team up for limited periods of time. The Summer of 2v2 was just this past July, but players are already clamoring for more of that sweet, sweet team-based action. The fans have... | Read more »
The best deals on the App Store this wee...
It seems like the week's only just started, and yet here we are with a huge pile of discounted games to sort through. There are some real doozies on sale this week. We're talking some truly stellar titles. Let's take a look at four of the best... | Read more »

Price Scanner via MacPrices.net

13-inch 2.3GHz MacBook Pros on sale for $100...
Amazon has the new 2017 13″ 2.3GHz MacBook Pros on sale today for $100 off MSRP, each including free shipping: – 13″ 2.3GHz/128GB Space Gray MacBook Pro (MPXQ2LL/A): $1199.99 $100 off MSRP – 13″ 2.... Read more
New iOS 11 Productivity Features Welcome But...
The iOS community is in late summer holding mode awaiting the September arrival of the iPhone 8 and iOS 11. iOS 11 public betas have been available for months — number six was released this week —... Read more
Samsung Electronics Launches New Portable SSD...
Samsung Electronics America, Inc. has announced the launch of Samsung Portable SSD T5 – its newest portable solid state drive (PSSD) that raises the bar for the performance of external memory... Read more
TrendForce Reports YoY Gain of 3.6% for 2Q17...
Market research firm TrendForce reports that the global notebook shipments for this second quarter registered a sequential quarterly increase of 5.7% and a year-on-year increase of 3.6%, totaling 39.... Read more
Sale! 10-inch iPad Pros for $50 off MSRP, no...
B&H Photo has 10.5″ iPad Pros in stock today and on sale for $50 off MSRP. Each iPad includes free shipping, and B&H charges sales tax in NY & NJ only: – 10.5″ 64GB iPad Pro: $599, save $... Read more
Sale! 2017 13-inch Silver 2.3GHz MacBook Pro...
Amazon has new 2017 13″ 2.3GHz/128GB Silver MacBook Pro on sale today for $100 off MSRP including free shipping. Their price is the lowest available for this model from any reseller: – 13″ 2.3GHz/... Read more
WaterField Unveils Collaboratively-Designed,...
In collaboration with customers and seasoned travelers, San Francisco maker WaterField Designs set out to create the preeminent carry-on system to improve the experience of frequent fliers. The... Read more
Miya Notes Mac-Client for Google Keep (Launch...
MacPlus Software has announced te launch of Miya Notes for Google Keep 1.0, a powerful Mac-client for Google Keep. Millions of people use Google Keep on their phones and online, but a convenient Mac... Read more
Apple refurbished iMacs available starting at...
Apple has previous-generation Certified Refurbished 2015 21″ & 27″ iMacs available starting at $849. Apple’s one-year warranty is standard, and shipping is free. The following models are... Read more
2017 13-inch MacBook Airs on sale for $100 of...
B&H Photo new 2017 13″ MacBook Airs on sale today for $100 off MSRP, starting at $899: – 13″ 1.8GHz/128GB MacBook Air (MQD32LL/A): $899, $100 off MSRP – 13″ 1.8GHz/256GB MacBook Air (MQD42LL/A... Read more

Jobs Board

Business Development Manager - *Apple* Medi...
Job Summary Apple Music is a single, intuitive app that...- all in one place. You can stream any Apple Music song, playlist or album, and download it Read more
Development Operations and Site Reliability E...
Development Operations and Site Reliability Engineer, Apple Payment Gateway Job Number: 57572631 Santa Clara Valley, California, United States Posted: Jul. 27, 2017 Read more
Frameworks Engineering Manager, *Apple* Wat...
Frameworks Engineering Manager, Apple Watch Job Number: 41632321 Santa Clara Valley, California, United States Posted: Jun. 15, 2017 Weekly Hours: 40.00 Job Summary Read more
Program Manager, *Apple* Pay Business Opera...
…Manager to deliver and sustain a seamless user and support experience for Apple Pay Cash, the upcoming person-to-person payments feature in iMessage. On the Business Read more
Sr. Software Engineer, Core Services, *Apple...
…You will be part of the server team that powers various features within the Apple client applications - iTunes, App Store, iBooks, Podcast, Apple Music etc. You Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.