Monthly Archives: May 2012

Cocoa, Apple and PureBasic

PureBasic on Apple computers is now a long history but was not always a love story. Back in october 2005, the first version of PureBasic for OS X was released. We spent almost a year to write the PowerPC support for the compiler, which was a real challenge. Believe it or not, 4 months later, the first x86 mac was out with Apple touting all the benefits of the new new x86 processors and letting down the good old PowerPC. That’s was quite a shock for us and it was obvious than all the hard work put in the PowerPC version was lost, as no major mainstream OS run on these processors. So far so good, as x86 was already support on Windows and Linux version of PureBasic, we thought it would be a peace a cake to support OS X. Not really. It was a nightmare to make it work, as Apple forced all API call to have the x86 stack 16 bytes aligned ! PureBasic indeed wasn’t designed for such stack alignment on function calls, as Windows and Linux don’t need such strict rules (btw, it was never mentioned in the Intel doc as well). So we overhauled all the calling code in the compiler to add exception when calling a function or procedure in PureBasic OS X x86. It definitely took some time, as the first public version to support it was released in http://www.purebasic.com/news55.php”>december 2008 (granted, we did some other thing in between but it gives an idea).

But that’s not the end of the story. When we started the port of PureBasic on OS X in 2003, we decided to use the Carbon framework as it was the advised framework for C programmer. All PureBasic functions are done in C on other platforms so it was the right choice at the time. Doing all the GUI commands (Window, Gadget, Menu, ToolBar, StatusBar, 2DDrawing, Drag’n’Drop etc.) for Carbon requiered a lot of efforts, as these libraries are big and fully featured. The Carbon API isn’t very well designed, old school, and morever plagged with redraw and clipping bugs. We added tons of fix only to have something almost working. But if you look in the PureBasic bug forums for OS X, you will find a lot of small remaining issues. Ok, it wasn’t perfect and hard to achieve, but it was working. And Apple ditched it once again. In 2007, Apple announced than the Carbon based application won’t be supported in 64 bit mode. Adobe, Microsoft and several other major companies complained about this fact but the decision was made and here again we knew we would one day rewrite the whole PureBasic command set using the Cocoa alternative. We don’t have that many user on OS X, as it still have nowaday a small user base compared to Windows, but the work put to support OS X outweigh the other OS by a great factor. That’s interesting to understand how companies handle their user base. Apple, which both do hardware and software always push the software forward quickly, and deprecate its hardware in the same time. You want the new OS ? Buy a new mac. The developers are advised to follow as well, and if they don’t want to, that’s not Apple problem. Microsoft on the other side don’t do hardware, so they want their OS to run on any possible PC. Very old PC can still run Windows 7, granted you get enough memory. Microsoft takes care of their developers and of backward compatibility. Here is a small quote from Joel’s blog which resumes the thing:

I first heard about this from one of the developers of the hit game SimCity, who told me that there was a critical bug in his application: it used memory right after freeing it, a major no-no that happened to work OK on DOS but would not work under Windows where memory that is freed is likely to be snatched up by another running application right away. The testers on the Windows team were going through various popular applications, testing them to make sure they worked OK, but SimCity kept crashing. They reported this to the Windows developers, who disassembled SimCity, stepped through it in a debugger, found the bug, and added special code that checked if SimCity was running, and if it did, ran the memory allocator in a special mode in which you could still use memory after freeing it.

Microsoft don’t deprecate an API, they still support it, side by side with the new one. That’s more work for them, but million of developers don’t have to rewrite they code from scratch at every major Windows version. And more important, binary executable still work, without a change. That’s two way of handling progress, and none are really bad. Indeed from the PureBasic point of view, we prefer to focus on new features than rewriting our working toolkit in another technology.

That said, we do care about our community and we promized a Cocoa support for OS X some time (years) ago. As Apple is pushing even more with the MacOS X AppStore which will soon banish Carbon applications, it was the right time to dive into Objective-C and the new framework. Timo (Fr34k) did the base framework for the Gadget and Window library in Cocoa and run prelimary test between regular C libraries and Objective-C one. The results were concluding, and I take back his work and continued it. After one full week and half on the Cocoa framework, I have to admit that’s it’s much superior to Carbon, and I would like to share this experience with you. Once you get used to the very strange bracket based Objective-C syntax, you can achieve the same work in much less coding lines:

ScrollAreaGadget
Carbon: 487 lines
Cocoa: 163 lines

SpinGadget
Carbon: 379 lines
Cocoa: 254 lines

ButtonImageGadget
Carbon: 290 lines
Cocoa: 110 lines

We got similar result in other gadget files. Ok, but the Carbon API is known to be verbose due to callback and old design. How does it compare with other OS ?

ScrollAreaGadget
Cocoa: 163 lines
GTK: 323 lines
Win32: 570 lines

SpinGadget
Cocoa: 254 lines
GTK: 487 lines
Win32: 331 lines

ButtonImageGadget
Cocoa: 110 lines
GTK: 284 lines
Win32: 480 lines

All in all, Cocoa wins hands down. Why is that ? To be honest, Win32/GTK PureBasic implementation are for now more mature and tested, so it includes many little fix here and here. That said, Cocoa is a modern API compared to Win32 and GTK, and is object oriented, which means you can chain the calls. For example:

[[[NSTabView alloc] initWithFrame:NSMakeRect(x, y, Width, Height)] autorelease]

In traditional C, you will have 3 lines:

alloc()
initWithFrame()
setAuroRelease()

Which brings us to another nice feature: the autorelease pool. Objective-C use reference counting to automatically free the objects when no-one is using it. So you don’t have to track every free, and in the end it does save some code.

Ok, that’s all for now, Cocoa is on the track and we are making great progress. That means than the next major release of PureBasic will probably brings it as default toolkit and, as a bonus, introduce 64 bit support !