Saturday, December 26, 2009

TimeLine view - rollovers

Each row of the TimeLine header view has two areas that are active. One is the drawMode and has a popup - the other represents the locked status of an item. These appear as graphics in the TimeLine header. I have decided to make these active areas distinct by making them behave as rollovers. The effect that I am looking for is quite simple - as the mouse goes over the active area I want to draw a grey oval. This will also provide an opportunity to draw a popup arrow for the popup. Adding the arrow so that it always draws makes the header look cluttered - only drawing this in the mouse-over state will make this a little cleaner.

The simplest way I found to do this is to use the NSTrackingArea. My aim was to add a NSTrackingArea for each visible active area.

To do this I added an updateTrackingAreas method to the view - in here I dispose of any existing tracking areas, and then to loop through all of the visible rows and for each to add a tracking area for each of the active areas on the row. When you construct a tracking area you pass in a NSDictionary of userInfo - here I pass in details of the row and the particular active area it represents. The updateTrackingAreas method is called when the header view scrolls or is resized - for the moment this is enough.

When you establish tracking areas on a view mouseEntered and mouseExited methods of your view will be called as the mouse enters and exits the view. here you need to get the relevant areas to redraw - I affected a method setNeedsDisplayInRow that is little more that a sprinkle of sugar for setNeedsDisplayInRect.

My guess is that the procedure for getting a rollover to work for a cell in in an NSTableView would be pretty much the same - though you might need to updateTrackingAreas in more situations (for example when table rows are resized).

Currently the drawing is still handled by the header view - but I plan to move this into a NSCell subclass.
An active area with a rollover.

Friday, December 18, 2009

TimeLine view - making the header active

In the TimeLine view the header is not a passive information-only structure it is active.
  • The text is editable.
  • The "Lock" icon works as a checkbox.
  • The "Draw Mode" icon is a popup menu with four states.
This is what one of the popup menus looks in the windows version if Cello.


The way that I plan to accomplish these active areas are by using subclasses of NSCell and friends. There is, for example, a NSPopupButtonCell that handles a popup menu button.

NSCell and it's derivatives are classes that encompass everything that is needed to draw a particular object, say a popup menu, and handle it's behavior. It is everything except the view in which it is drawn. As with all things in Cocoa they are there for the taking - you can use them as is or subclass them as you please. The way you use them is really easy - if you want them to draw then you:
  • Set it up
  • Ask it to draw in a given rectangle in a given view
If you want to handle a mouse down then you:
  • Set it up
  • Ask it to handle the mouse down
All the Cocoa controls (for example NSButton) use a NSCell subclass to do the drawing etc. If you want to see how they work - check out the Cocoatron project. You can download the source and see just how simple the cocoatron NSButton is.

I have started by crudely hacking in the NSPopupButtonCell
into the TimeLine view and getting it to draw and to handle the mousedown - the menu is just a dummy. My plan is to refine this (stepwise refinement) until I get what I want.

Sunday, December 13, 2009

TimeLine view - header with icons

I have added the drawing of icons to the header row. I have taken the existing graphics from the PC version and quite quickly converted them to individual tiff images in photoshop. I am for the moment just reusing the PC images. When Cello is finished they will need reworking as they don't have that OSX feel. My thought is to hand this part of the project over to someone else - it really is something to worry about another day.

The drawing of icons is quite straight forward. I just figure out the point to draw the icon so it is centered in its rectangle and call compositeToPoint:operation and that is about it.
If you look closely you can see that there is a white bloom (square) around the icons - this is an actual transparency issue with the graphics (something wrong with my photoshop efforts).

Saturday, December 12, 2009

Cocoa and Drawing truncated text

To properly allow for long names of objects in the time-line I need to draw truncated text.
Untruncated Text

What I mean is that I want to truncate the text if the area is to small for the text and then to have some ellipses that show where the truncation occurs. This was second nature to me in my days as a ToolBox (Carbon) programmer but fathoming it out under Cocoa tool a while. Whatever I tried failed - and it seemed that the Apple docs failed me.

In a tight corner Google is a good friend and I found the blog-post from Preston Jackson. It is an example of the kind of blog-post I find most useful. A problem and a solution - with a code snippet. Thanks Preston.

I copy/pasted his code and it worked. Then I integrated it into the code that should have worked but didn't and it failed. It took (unbelievably) an hour to get to the bottom of the problem. In full numpty horror I realized that I was calculating the width of the text I was and changing my destination rectangle so it would be that width.

With the truncation the text looks like this:

TimeLine view - header regions

Working on the TimeLine view I have started getting the row headers to draw. I am stepwise refining the row header drawing until I have the row headers drawing correctly. The PC version of cello draws row headers like this:
So my start is to take the single rectangle for a row and to divide it into four parts. The text part will grow and shrink horizontally - the other parts are fixed (they will display icons). I did this by writing a small C++ class that just calculates the dimensions. I could have done this in C, or Cocoa but sometimes C++ is closest to hand - and it fell out very simply. I altered the drawing to reflect the calculated rectangles. It is a temporary debugging measure I just frame the rectangles. - so the evolving headers now look like this:

Friday, December 4, 2009

NSScrollView - problems

I have been having a strange problem scrolling in the TimeLine view. The issue is down to my understanding of coordinate spaces under "normal" (not flipped) circumstances in cocoa. The coordinate space is much as I expect - the bottom left corner is (0, 0). However when you come to NSScrollView things are a little strange. If the position of the content view also starts from the bottom left corner. This is 100% logical. What I did not count on was the effect when the content view is smaller than the NSScrollView. So, of your list, is smaller than the NSScrollView you can easily have this situation. What happens is that the bottom of the content view is placed as (0, 0) within the NSScrollView.The problem can be seen quite clearly if I expanded my evolving TimeLine so that the NSScrollView is larger than the content area. It looks as follows:

It took me a while to figure out the fix. MBTableView dealt with the problem forcing all the views to be flipped - so that (0, 0) is the top-left so it did not provide any kind of example. To get an example I downloaded the source code to CocoaTron. CocoaTron is an open source implementation of the cocoa frameworks. It is a cool project (don't let the web-site fool you it is actively developed) and the source code is there for you. You can find it here.

I pulled the CocoaTron source and had a look at their implementation of NSTableView. The solution is to grow the content view so that it is never smaller. Each time you resize the NSScrollView the NSTableView recalculates and repositions its self.

The solution:Add an override to resizeWithOldSuperviewSize that makes the content at least the size of it's superview. My resizeWithOldSuperviewSize would up looking like this:

-(void)resizeWithOldSuperviewSize:(NSSize)oldSize {

[super resizeWithOldSuperviewSize:oldSize];

[self reloadData];

}


My reloadData has also changed:

- (void)reloadData

{

.... stuff

NSRect contentRect = NSMakeRect(0, 0, _numberOfColumns * _columnWidth, _numberOfRows *_rowHeight);

contentRect.size.height = MAX(contentRect.size.height, [[self superview] bounds].size.height);

[contentView setFrameSize:contentRect.size];

.... stuff

}



Thursday, December 3, 2009

TimeLine - sketching out more

I am slowly shapping up the timeline. I am working with a scratch target in the main project and doing occasional Git commits. The commits are little more than line in the sand that I can undo to. My approach is to start simple and to refine slowly.

Basic Topology (header areas)

Starting with the basic ytopology I refined it by adding NSScrollViews.

Basic topology (with scrolling)

The final shot of this post shows some dummy content. The beginings of what will happen in the row headers is there. I have coppied the draw code of the rows into the main content view so that I can debug the drawing. I have some strange problems that I guess are related to the coordinate system that is prelevant in cocoa - which to me (cooming from QuickDraw coordinates) still feels a litte odd.


Some dummy drawing of row headers and rows

Monday, November 23, 2009

TimeLine view - first brush strokes

I have started implementing the TimeLine view - and implementing it from the ground up. My approach is to start with the basic topology and then to add flesh to the bones. The PC view has row labels of user determined width. I can kick this off in a small sample project - I should be able to get the basic structure of what I need working outside of Cello. So I started by adding a new (temporary) target to XCode and sketched out a basic splitter with two views in interface builder.

The drawRect methods of the views just fill the two rectangles with grey.

As a next step I have broken the two views into several sub views. The row header, column header and content are all need to be within NSScrollViews. So I have added those.

On from this I have started sketching out the protocol for the DataSource modeling it roughly on the DataSource in the NSTableView. My idea is to start with a protocol that is close to how I am implementing the TimeLine - initially something very much like a table. My plan is then when the basic table functionality is working to shift directions and refine the protocol so it more closely resembles the data that is presented and required by Cello as it stands.

Sunday, November 22, 2009

NSTableView vs MBTableGrid - the verdict

I have spent some time looking at NSTableView and also the open source MBTableGrid. What I have been doing is playing around with them in test applications to try and get a measure of the two approaches. In the end I have decided to write my own view from the ground up. Looking at the MBTableGrid example has given em a really good idea of what it will take to do it - and the work will not be greater from what I will need to do to get MBTableGrid customized and wrinkled into the form that I need. MBTableGrid is closer to what I need than NSTableView.

Thursday, November 19, 2009

NSTableView vs MBTableGrid - the trial

The main cello UI is comprised of three views, FrameView TimeLine and ActionView. Together these views comprise the majority of the editing functionality. My intention was to start with the FrameView. The FrameView is used to draw the the items at a given point in time. So when you sketch, say, a box you do this in the FrameView. It seemed like the most important view to start with. There is, however a really close linkage between the views - so starting with the TimeLine view seems the simplest. We shall see:

In the PC version the time line looks like this:

It is more-or-less a list of a single column with row and column headings. The row headings contain active controls - as do the rows themselves. The column heading is a has the time-ruler and is also active.

As far as implementing this in cocoa I can see two choices
  • Implement this strange list like thing myself
  • Use the cocoa NSTableView
The best course does not seem immediately obvious to me. One of the benefits of writing a blog is that when writing things you can think about them in a slightly different way. One of the things that occurred to me while writing this is that the table is not actually a table of a single column - it can be thought of as a table of many many columns. Each time interval (typically something like 1/15th of a second) can be thought of as a single column - this would seem to offer some simplifications in the implementation.

In trying to determine the best course of action I have tried to enumerate the various things that need to be done with the time line.
  • Items in the row header need to be editable.
  • Items there are buttons and popup menus in the row headers
  • Rows need to be selectable
  • Cells have items that can be added/deleted and removed
  • Some items can stretch over more than one cell
  • Items that stretch over more than one cell appear as a "whole" - they are drawn as a whole
  • There is a row (the sound track row) that does not (currently) have any editable elements.
  • The width of the row area needs to be resizable
  • The header area is not a standard table header
Looking at this I can try and figure out what the best way forward should be. Also into the mix comes MBTableGrid - a set of classes that draws a "Spread Sheet" type widget written by Matt Ball - that could be a basis for a non-list approach. The Author has solved a number of the problems that I would face - there is a separate row/column area, it supports inline editing. The code can be found here.

The NSTable approach has a few stumbling blocks:
  • Tables don't have row headers - this could be be implemented by a separate parallel - list. you just have to sync the scrolling and selection.
  • I would need a different header - fortunately the table header can be sub-classed.

Monday, November 16, 2009

NSDocumentController - Reusing a single window across multiple documents

A further twist to having a single document visible at any one time is that I would like to keep a single window and reuse it. The way I have done this is as follows
  • When I get the NSApplicationWillFinishLaunchingNotification I create the window controller and window. I do this by reading in a nib file that has my subclass of a window controller and a window.
  • In the makeWindowControllers method of my document subclass I call addWindowController to add my global window controller.
And that is about it.

Sunday, November 15, 2009

NSDocumentController - Maintaining a single document

I have been trying to figure out the best way to structure things to support the concept of the "main frame". Under Windows applications generally seem to have a main frame. This is the single key window that is central to the application. The OSX world is different - you generally have multiple windows one for each document. As a Mac user, now working windows much of the time. I find the paradigm a little strange at first. That said once you are accustomed it is fine. Also as I have mentioned before it is something that you see in some consumer apps on OSX so I am keeping this behaviour.

The trick with these things is, as ever, to find the path of least resistance. Now that I am working with Cocoa I want to do the same on the Cocoa end. I don't want to fight AppKit I want to dovetail in as well as I can so that I have to do as little as possible.

Looking at AppKit I definitely want to retain an NSDocument. I want this as NSDocument hooks into the undo manager really nicely. I will have to somehow mesh Cello's undo manager with NSDocument but that is something that I will look at later. The NSDocument as support for all the open and saving and I can hook into this.

So what I have done is write my own subclass of NSDocumentController - this is the master controller for all of my documents (the thing is I only ever have one). So my sub class will ensure that there is just one document - so if you open a document it will close the existing one.

I started by adding two methods to my document controller

- (void)addDocument:(NSDocument *)document {
[super addDocument:document];
}

- (void)removeDocument:(NSDocument *)document {
[super removeDocument:document];
}

So I could add breakpoints to check where these things were called. I could add breakpoints using GDB to the NSDocumentController methods - but I like this way. I wrote a new method that closeAllDocuments to close all of the documents (there should only ever be one). And then call that at appropriate times.
  • - (IBAction)newDocument:(id)sender
  • - (IBAction)openDocument:(id)sender
Finally I made my document controller my application delegate (if I need to I can always change this) so that I could implement the two methods:
  • - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
  • - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
And that takes care of the best part of it.

While figuring this out I came accoss the following post that proved very usefull here. The post is in Japanese which I was not able to follow - but the code was usefull.

Wednesday, November 11, 2009

Kon and Bal - NSWindowController won't show my window

I am trying to rationalized the Windows idea of a MainFrame with the Cocoa document model, and in that deal with the meshing of C++ and Cocoa. Out the box Cocoa will give you a window per document - but infinitely configurable cocoa gives you the tools to skin the cat as you want it.

What I have been trying to do is get my C++ MainFrame to create a NSWindowController (subclass) and to create and show the window. This sounds easy enough - and indeed should be. The steps are like this:
  • Add a nib with the window and the FileOwner being the window controller.
  • Add a call to [myController initWithWindowNibName:@"NibName"] to load the nib.
  • Show the window with [myController showWindow:blah]
But nothing happened. The window did not show.

I had a problem like this six or eight months ago with another project I was working on and I had not connected the window to the controller in my nib. Sure enough there it was. But the problem did not go away.

In the debugger I could see that the controller had a window and that window's flags showed that it had become visible - but still no window was visible. Once I saw the window for the briefest moments - but flipping windows when messing with the debugger made it unrepeatable.

In the end I went back to an old technique of debugging that I fall back to when I can't fathom things like this. I created a subclass of NSWindow and overrode the alloc, dealloc and some other key methods, and changed the nib so that my window was of this type. In the implementation of my TestWindow class I did no more than called the parent method. What this did was allow me to put breakpoints on the window's key life cycle moments. What was going on in my head was the thought that either that somehow:
  • I was not creating a window at the right moment (what this might mean I did not know)
  • The window was not being shown - the calls that would show the window where not being made.
  • The window was being disposed immediately after I had created it.
As few moments in the debugger and I could see that my dealloc was being called. The controller was being disposed in an AutoReleasePool - I had an owner count problem.

BAL: Nasty.

KON: Yeah.

Monday, November 2, 2009

Meshing Cocoa with C++

One of the key issues I am looking at is the problem of having a code base that is written as C++ classes and meshing that with an application framework that is written in Objective C. My rough plan at the moment is to have a parallel Objective C object for each C++ object that appears directly in the UI. So, for example, there is an C++ object in Cello that is what is called the FrameView. This is one of the central classes that appears deep through much of the cello code. My plan is to split this into two

  • IMainFrame - a C++ subclass
  • CHMainFrame - an Objective-C wrapper class
I don't imagine the Objective-C wrapper to be a simple wrapper. What I imagine is that it will present what is needed of the C++ class to the objective C world in doing this there will be things that make sense to be written here.

Sunday, November 1, 2009

Your document contents here


This is a screen shot of the first file that has been opened by the cello application. The application will open a cello document that has been created in the PC version of cello. It openes the document much as the test application did but it is wired to the beginnings of a "propper" application.

Sunday, October 18, 2009

Debugging Individual CPlusTestRig Test Cases

Having got the unit tests working in the debugger I don't really want all the tests to be executed each time I run the debugger. I just want to work with the problem test.

The easiest method I know of is just linking in the tests that you want. It is what I have used in the past when fixing unit tests (prior to getting the debugger to work I used NSLog calls and just looked at the output - my programming start predates symbolic debuggers and if you go old school you can still find bugs and fix things).

I have named all my tests files so that they end in _test and then the file suffix. This means that I can: 


  1. Select all my test files in the search widget in XCode by typing _test.cpp and then in the main area choose the tests that I do not want
  2. Click on the Info button in the tool bar to get info on all of the tests
  3. Select the Targets pain in the info window and turn off the tests that I don't want to run.


As I have boith .cpp and .mm files this is actually a two stage process - but it is very simple to do.

Wednesday, October 14, 2009

Debugging CPlusTestRig UnitTests

Having started work on the user interface I am doing a fair bit of reorganizing. In this reorganization I have been changing the way that UI related components are being registered. What has happened is that in the early stages of development I had roughed-out stubs installed as the needed UI components - but these no longer load. The upshot of this is that I have made the first progress am ready to commit my changes to the library but my unit tests are failing - components are missing. I am getting crashes.

Pinning down these sort of problem with a debugger is generally quite straight forward. My frustration is that out of the tin the debugger does not "just work". OSX has made me lazy - I am used to things just working.

The best set of hints I have found on this are on Chris Hanson's blog - this is for testing cocoa frameworks. I am using CPlusTestRig but there is enough there to figure out what you need to do. This is my recipe


Turn off the automatic running of unit tests.


I did this as I wanted my unit test related files to build but I did not want the shell scripts that executes them to run. If it does run it will run outside of the debugger. To do this:
  • Selected the Unit Test target in the files
  • Choose get info from the tool bar
  • Put a hash (#) in front of the line "${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests" this has the effect of commenting it out. If you do it this way you can remove the hash character and be back where you were.

Create a new Executable 


  • Choose Project>New Custom Executable
  • Give it a name (I choose "Debug UnitTests") and enter "Tools/CPlusTestRig" in the Executable path
  • In the window that appears click on the Arguments Tab and add in the name of your test bundle - if you have spaces in your name you need to escape them

Run


  • Set your active executable.
  • Hit the debug button on your toolbar.


Saturday, July 25, 2009

Fun and games with owner counts

Working on the UI my current short-term target is to open a file. The results of this will not be ostensibly much different from the test bed application which could open, save and publish a file except that it involves putting in the beginnings of a skeleton for the UI of the final app. The skeleton is a mix of Cocoa C++. There are C++ subclasses of existing Cello objects and Cocoa wrappers.


I don't like checking things into the project that don't compile and in some sense work. I view checkins as a progression forward so working on my next checkin I have been dealing with owner counting problems. 


Cello predates boost, or at least does not have any boost in it and owner counting is done through inheritance from custom classes and hand-rolled templates. This works fine but there have been some wrinkles with classes that use the 'interface' extension (which is I believe a Microsoft extension). I have replaced interfaces with straight subclasses (for the moment at lease) and in this there have been uninteresting wrinkles with the owner counting mechanisms. Just uninteresting stuff that you need #ifdef your way through.

Monday, June 29, 2009

UI - Initial Approach

After a bit of a break I have started picking up on Cello again, once again I have some free evenings.

Having got to the stage where I can open and publish test files I now have start the serious work of the user interface. My current thoughts are to start with the existing view hierarchy and to use it to wrap cocoa views. For example there is a time-line view. This view manages a time-line and the events that exist on it. There is a time-line base class as well as sub-classes, there are commands that are originated from the time-line etc. The path of least resistance would seem to be to keep this structure and to wrap cocoa views behind the scenes get the meld that way.

Wednesday, March 25, 2009

XCode - Development Version Numbers

In the Cello development I have numbered each checkin. This checkin number is recorded in a tag-line in each file that is checked in, and in the checkin comment (or message). Once I have reached the stage of building the test applications I have been careful to build a version of the test application with the build number and archive it. The idea behind this is that when I find a regression or performance anomaly I can test against the checkin points and find out where the problem was introduced. Until now I have numbered the builds individually after they have been constructed but it is possible to get XCode to do this for you automatically.

To do this I did the following:
  • Added a new file history.xconfig to the project.
  • In history.xconfig added a single line CELLO_BUILD_NUMBER=0129
  • Changed the build settings so that they are "based on history.xconfig". You do this by choosing the build settings from a the "based on" popup that appears in the build settings pane.
  • Changed the Product Name in the build settings to Cello $(CELLO_BUILD_NUMBER)

The effect of this is each time I change history.xconfig Cello will be built with the appropriate build number.

Sunday, March 22, 2009

The Joy of GIT

Once you start getting accustomed to GIT it becomes quite addictive. I have started using GIT on another project. Despite using use only a fraction of it I have found it so fast and flexible that I have decided to move the Cello project over to GIT.

To install Git on your machine the easiest way to go is to use MacPorts. MacPorts is a cunning system that will install a package and all it's dependent packages, downloading, building and linking as necessary like magic. Once you have installed MacPorts installing a package like GIT is a breeze. Pop open the terminal and type

$sudo port install git-core

To import a CVS project into GIT you will need to install cvsps. Again this can be done with MacPorts

$sudo port install cvsps

And you are good to go, well to migrate your CVS repository to GIT. For me the following command imported the project in its entirety

$git cvsimport -v -C path_to_my_git_repositry my_module

Tuesday, March 3, 2009

UI - BabySteps

In building the UI I am planning to take baby-steps. There are two reasons for this
  • Small steps are easier
  • I have a tiny amount of spare time
As things currently pan out I can only spare, at most, a couple of hours a week to work on Cello. A philosophy that I take when clearing the kitchen at home, a task that I find perpetually bewildering, is to do something productive with every action and not to worry too much about the final result. The accumulation of actions results in a tidy kitchen. So I take baby steps with the UI.

Sunday, January 25, 2009

UI - Preparing for Power

I had a friend who was in a member of the Revolutionary Communist Party and was planning to attend a meeting optimistically entitled "Preparing for Power". At the time it really tickled me. and has become one of those wonderfull phrases that has stuck with me.

So for my part I am "Preparing for UI". These are the small baby steps that are required to start doing something. I have split the project into a library that has most of the blood-and-guts (the engine) and the test application links against it. Following this I have created a new target (that is really a copy of the test Application) called Cello. This will be the finished Application and this is where the UI will live. I have always found XCode an awkward beast to handle so adding targets is a surprisingly cumbersome to manage. XCode is not a bad tool but for me, and it may well be a personal short coming, it seems to fly against the idea that "simple things should be accomplished simply".

Wednesday, January 7, 2009

Re-factoring

Prior to starting on the UI I have been doing some re-factoring. I have read that the important thing when re-factoring is that the code still works. My experience supports this. The ideal situation is that you re-factor in small steps and intersperse these steps with running unit tests that will ensure that you haven't broken anything. In the case of Cello as most of the work I have done is for functionality that allows Cello to mesh onto OSX, I have also written a lot of Unit Tests so I feel relatively secure about a modest amount of re-factoring.

The main things that I am doing re-factoring is:
  • Working through consistent naming.
  • Wrapping most the core foundation functions as methods.
Wrapping of core foundation functions as methods is something that I first came across in ACS (a part of MacApp). ACS aimed to present the what was originally the tool-box functionality as a set of C++ objects. In later versions following the introduction of CoreFoundation it did this, where possible, by defining the anonymous types. So in the case of CFData, a CFDataRef and CFMutableDataRef are defined as:
typedef const struct __CFData * CFDataRef;
typedef struct __CFData * CFMutableDataRef;
What ACS did was to then define the anonymous __CFData and add methods to it. So to add a method that would wrap CFDataGetLength it would did something like this:
struct __CFData
{
CFIndex GetLength() const;
};
and then defined an implementation for GetLength in terms of CFDataGetLength
inline CFIndex __CFData::GetLength() const
{
return CFDataGetLength(this);
}
When I started work on the Cello project I actively resisted this in favor of calling (typically) core foundation directly. What I found was that it made life a lot easier if I wrapped all the 'create' or 'copy' functions so that they returned boost::intrusive_ptr wrapped CF types. I did this as I used boost::intrusive_ptr to take care of all the ownership/ownercounting issues. When working on the Sound part of Cello I 'rediscovered' this ACS style wrapping, partly because it just made the code easier to read.

It means that instead of calling:
int length = CFDataGetLength(myData);
You write:
int length = myData->GetLength();
If you are dealing with boost::intrusive_ptr it eleminates a lot of 'get' calls so instead of
int length = CFDataGetLength(myData.get());
You write:
int length = myData->GetLength();
The other thing that comes into play is that I have had to wrap small amounts of Objective-C so that it can be used in C++. I have opted to keep Objective C out of the general C++ not just to properly isolate the complete madness of two different incompatible types exception handling but also to keep things simpler. It is generally natural to express these as C++ methods