Sunday 22 February 2009

Cloud computing

This weekend I was reading an article on cloud computing . And to be honest I'm very skeptical on the success of this new paradigma.
The idea behind cloud computing is that you have mega-datacenters out of which you run applications (f.e. Google Apps), so lowering the cost for companies (the cost of owning an own IT department).
Too me this is again some marketing hype (computer vendors trying to sell services).

I can agree that some basic services  can be offered over the net, but complex applications ? No never.

Basic services like storage over the Net seems logical too me (I use box.net for example). But apart from that ? Will you use Amazon SimpleDB for example ?
Amazon SimpleDB offers you a (simple) database over the Internet, but what is the use of it ? Everybody knows that making a database application performant enough is already a big challenge in a total controlled environment. How can you ever make it performant when your database is somewhere sitting on a remote server and you only have access to it over the Internet (and behind a firewall)?

In my company for example  we have a 200GigaBit connection to our private datacenter (over a private network) and still we had to invest in very expensive routers with caching.

And not to mention  the next level of Cloud computing : applications over the Internet.

If you have ever used Google Apps and Google Docs for example, then you understand that those applications are miles (not to say lightyears) away from suites like NeoOffice or MSOffice.

And of course don't forget things like security, privacy, reliability etc.

Think for yourself : would you put all your company (or private ) data on to the servers of Amazon,Google, IBM or Microsoft ?

Tetris and Maze

I'm currently busy extending the Tetris application with some visual's, more features like highscores, levels etc.
I come back to that because I found some nice things with the NSImage class.

I'm also busy with a Maze application, the purpose will be to escape a maze using the SMS (so this will be for Macbook  and Powerbook only).

Cool IPhone application

 This has nothing todo with objective-c or Cocoa , but this is a damned cool IPhone application.

This application  runs an OS 9 Mac Emulator on your iPhone. So now you can have those good old days Mac application back on the IPhone (MacPaint here we come ).
This emulator is based on MiniVMac.

I don't known if its usefull but it shows at least the capabilities of the IPhone.

Note: the only caveat there is , is that you need a Mac Plus ROM image, and where on earth do you get that ?

Saturday 21 February 2009

Sudden Motion Sensor

I just found out the class library SMSLib, with this library one can access the accelerometer inside your Macbook or Powerbook.
I'm just looking now how to use this library and to make some wrapper classes around it (maybe adding some notifications etc).

Its very exciting...

Tuesday 17 February 2009

IBAction and IBOutlet : what is this ?

During my programming efforts with XCode and Interface Builder , I never stood still what the meaning was of IBAction and IBOutlet.
I known that the identify an action or a field , but what are they ?
They are not classes or structs thats for sure.

But if you dig hard enough in the documentation of Apple, then you find out that they are nothing more than AppKit constants (and macro).
And IBAction is  just another name for void, they are used as syntax sugar for XCode and Interfacebuilder so that XCode&InterfaceBuilder can interpret the variables and methods correctly.

And IBOutlet is an empty macro.

You can find them in NSNibDeclarations.h

Conclusion: don't search for anything fancy, they are just void....

Friday 13 February 2009

Tetris : the implementation of a classical game in Objective-C/Cocoa

First of all the source code of the game can be found here. Background for the game can be found on wikipedia.

This implementation is a first attempt to implement it, in this version I was more intrested to get it to work than in the nice graphical aspects.
As you can see in the picture , it surely won't win a prize as the most sexy application :-).



This game again is an implementation of the classical MVC design pattern, with the difference that their are 2 views.

The model is a TetrisBoard (subclass of Board) on which you can move a piece (the so-called Tetrominoe (superclass of a set of pieces)).
The tetrominoe is the abstract superclass of all the tetrominoe's. It's very handy to model the pieces as a class, later on I can add things like a skin, or a another way of rotating. 

There are 2 views, the TetrisView and the TetrominoeView. The first one is the graphical representation of the  TetrisBoard; the second shows the next tetrominoe.

The model and the view(s) are connected via the TetrisController.

Thursday 12 February 2009

Delegation : a powerful concept

Delegation is an important OO concept, and is used a lot in the Cocoa framework. With the usage of delegation the developers of the framework gives the capability to other programmers to interfere with the execution of the code.

For example : in NSWindow you can set a delegate (via setDelegate:). Now when a window will close , the NSWindow object will send the message windowWillClose: to the delegate.
The delegate can now do some cleanup before the window actually closes.

With delegation you also avoid the need for subclassing ; this can be an advantage but sometimes a disadvantage.
The advantage is that you don't need to interfere with a whole class library (try to subclass NSWindow , you'll see that its hard work to get the subclass working properly).
The disadvantage of delegation is that the framework developer decides on the 'plug' points, if for example the windowWillClose: method was not delegated then you couldn't do anything before a window close and then the only option you have is to subclass and override the method.

Another example fo delegation is in the case of board game with different pieces that moves around. In this case you have for example a class Board and several classes of Pieces.
If we want to implement a method that tests if pieces are colliding or reaching the boundaries of the board we can do 2 things :

1. We can implement all logic in the Board class, the disadvantage here is that the class Board 'knows' the internal setup of all pieces.
And so it means that if we add a new piece, we have to change the method also

2. We can use the principles of delegation and delegate the test of colliding to each piece itsself (via method call like [aPiece hasCollidedOn: self] , where self is the board).
This has the advantage that each piece can implement the test like he wants , and because we pass the board as a parameter; the piece can still interrogate the board.

Later on I'll publish my implementation of tetris where I've implemented this type of delegation

Drawing in views : how to draw a grid ?

Drawing a grid in a view is rather simple, I do this often to better align my objects.
To draw a grid you can simply add the following lines of code to your drawRect: method :

(GRIDSIZE is a macro defined in the .h file of the view).

- (void)drawRect:(NSRect)rect {
// Drawing code here.
int width = rect.size.width ;
int height = rect.size.height ;

int i = 0 ;

 
// Set the color in the current graphics context for future draw operations
[[NSColor lightGrayColor] setStroke];

// Create our drawing path

NSBezierPath* drawingPath = [NSBezierPath bezierPath];

// Draw a grid
// first the vertical lines
for( i = 0 ; i <= width ; i=i+GRIDSIZE ) { [drawingPath moveToPoint:NSMakePoint(i, 0)]; [drawingPath lineToPoint:NSMakePoint(i, height)]; } // then the horizontal lines
for( i = 0 ; i <= height ; i=i+GRIDSIZE ) { [drawingPath moveToPoint:NSMakePoint(0,i)]; [drawingPath lineToPoint:NSMakePoint(width, i)]; } // actually draw the grid
[drawingPath stroke];

 

}

Help !?!, How to integrate a helpfile in my application

In every (non trivial) application we need help. When developping a Cocoa application using XCode we get the foundation for help for free. (In Interface builder their is a menubar foreseen for your window, in that menubar you see the menuitem Help).

By default , the help menuitem is connected to the showHelp: method of the firstResponder (or in the chain up of responders).
Now you can do 2 things, first is to override the default implementation of the showHelp: in your firstResponder :

- (void) showHelp: (id) sender { NSString* help = [[NSBundle mainBundle] pathForResource:@"Some Help" ofType:@"html"]; NSURL* url = [NSURL fileURLWithPath:help]; [[NSWorkspace sharedWorkspace] openURL: url]; }

The above method (I found this code on the Internet) will open a html file (Some Help.html) in a seperate browser.
Of course you need first to add the file to your project, otherwise it will not be published in the application bundle.

(To do this in XCode : open the folder 'Resources' , the press CTRL-, a context menu will appear and you select 'Existing files' ) :



This rather cumbersome, and your help is not nicely integrated in Apple's HelpViewer.

So a second solution is to use the HelpViewer functionality. And now a whole quest started....
I first started to read the Apple documentation on the subject, but it seems that the documentation is written by experts and for experts (preferably working at Apple).
I followed the instructions line by line and the only thing I got was the HelpViewer coming up with a blank page.

After hours of frustration (I almost threw my MacBook thru the window) and searching on the Internet I finally found a way to integrate my help files with HelpViewer.
So here are the steps to follow to get it done :

1. Create your help files and put them in folder (for example 'MyApplication Help' ). this folder will usually be a subfolder in your project. In the first page of your help (your homepage of the help) you need to add a meta tag in the head section :

<META NAME="AppleTitle" CONTENT="MyApplication Help">

ps: MyApplication Help is the name of your help book

2. Run the HelpIndexer, this utility can be found in Developer>Applications>Utilities. In the HelpIndexer you first select the folder in which you dropped your help files and then you press 'create index'.

3. Then you go to XCode (I assume your project is open) and then via Finder you drag-and-drop the help folder in the resources folder of your project.

4. In the Info.plist file you need to add to key-value pairs as follow :
key : CFBundleHelpBookFolder
string: MyApplication Help

key: CFBundleHelpBookName
string:MyApplication Help

5. Now you need to rebuild your XCode project, before you do a build first do clean all targets, otherwise your Info.plist will not be processed.

When you run now your application and press help, you'll see your help file appearing in the HelpViewer.
Also note that when you click the home button in HelpViewer you'll see your help appearing in the list of help book's.




Tuesday 10 February 2009

NSNotifications: a broadcasting mechanism

Notifications are a strong mechanism to broadcast messages to multiple recipients , and also to loosely couple objects.

Typical examples are :

- GUI elements that want to notify other GUI elements about an event. (for example : a window that closes can notify all controls on the window about the close).
- In a MVC application, the model can notify about changes in his internal state (internal variables that are changing).

To be able to use a notifications we need 2 things : a central broadcast component and a way to register an intrest for notifications (and a way to post notifications).

Apple in his Cocoa framework offers the following implementation :

1. The central broadcast component

[NSNotificationCenter defaultCenter]

The NSNotificationCenter is the class that implements the central broadcast component, and by sending the message defaultCenter you get a singleton instance of it.
Note that each application can only have one nsnotificationcenter.

2. Register for an interest in a notification

[[NSNotificationCenter defaultCenter]
addObserver:myInstance

selector:@selector(doSomethingWhenNotified:)
name:@"someName"
object:nil ] ;

With the above statement you register with the notification center the following :
when somebody (a class in your application) sends a notification with name "someName", then to the object myInstance the message doSomethingWhenNotified: will be sent.

Important note : the message doSomethingWhenNotified: must have the following signature :
- (void) doSomethingWhenNotified: (NSNotification *) notification

(= your notification message must accepts one argument of type NSNotification *).

Note 2 : This method is best called in the awakeFromNib method. Because then you are sure that your window is properly initialized.

3. Posting a notification

To post a notification you do the following :

[[NSNotificationCenter defaultCenter] postNotificationName:@"someName" object: nil ]

Note: this is for example used in a method which changes a variable.

General note : in both cases you see the "object: nil", instead of nil you can use any object, but then the notificationcenter will only post the notifications for that particular object.

Saturday 7 February 2009

Timers

During the development of the Game Of Life, I was wondering how I could capture mouse events and still running the application.

In a first , naive , implementation I had a for(..) loop which called the oneIteration method.

Of course this wasn't very intelligent :-). I had no chance to interrupt the program until the loop was finished.
Then I stumbled on 2 classes: NSAnimation and NSTimer.
In my case NSTimer was sufficient, I only needed a timer which would fire every second to launch the oneIteration method.

The important thing is that a timer will not interrupt a function in the middle of its execution (god forbid what for side effects that could have).

So my creation of a Timer is as follows :

[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(oneIteration)
userInfo:nil

repeats:YES]

In human language it means that I've created a repeatable timer with an interval of 1 second and that will send the message oneIteration to self.

Once a timer is created , it will automatically fire. If you want to force the timer to fire , just send the message fire to it.

2 notes here :

1. You cannot suspend a timer, you can only stop it (by sending invalidate to it).
2. Don't send release to an invalidated timer, I got multiple crashes in my application

So if you want to chance the interval of a Timer , then you have to invalidate the old one and recreate a new one

Frameworks

While I was busy writing Tetris (for Mac using Cocoa of course), I was also wondering how I could create a simple framework of my generic classes I wrote for the Game of Life.

In the Apple documentation they are referring to 2 types of frameworks, public ones and private ones.
The public ones you find in /System/Library/Frameworks and /Library/Frameworks.
Now for me, its not a good idea to put my frameworks in a public place, so thats why I opt to create a private framework in my own location (later on its a bit more difficult to use it , but at least I have full control over it).

The first thing we have to do is to startup XCode , and select File>New Project. In the popup that follows you select 'Cocoa Framework'



And click the 'next' button, you now get the opportunity to give a name to your framework.

In a next step, you'll add files, debug them etc etc (the usual development so to speak).
At some time you'll be ready for releasing the framework you made.

Of course , if you want to use your framework in other development projects you need to 'publish' your .h files (your header files).

And this you do in the project browser :



As you notice in the picture, you select in the project explorer 'Targets/name of your framework/Copy headers' . On the right handside you see all your .h files.
The second column says 'Role', now file by file you can change the role (you do this by clicking on the small triangle, you then get a popup with 3 choices).

Its important to change the ones you want to be public , by default they are all 'project'.

A last step is to build the framework and save it some where. A good convention is to save all your frameworks in a location called 'frameworks' (just like Apple does).
Changing the location you do in the project settings (XCode>Project>Edit Proj
ect Settings).



And now you build it and voila you have a framework.

Tuesday 3 February 2009

The Game of Life, the implementation

My own implementation of John Conways Game Of Life can be downloaded here.
Note that this implementation is far from ready, it shows the base concepts used but still need some polish to be really userfriendly and graphical attractive.

Screenshot :

The main concepts I used here are the following :

First of all I need a Model, in my case I created a class LifeBoard (a subclass of Board) . The abstract class Board just implements a basic gameboard with a variable number of cells. 
The LifeBoard class is the implementation of a gameboard for the Game Of Life, it implements the Conway algorithm. 
Note that we could use a strategy (design pattern) to delegate the algorithm to it. For the sake of simplicity this is not done.

The underlying datastructure used is a Matrix. (see previous blog messages for an explanation).

The next thing we need is a View,  in this case I created a custom view : LifeView (subclass of NSView).
This view just implements a simple visual representation of the LifeBoard. (a rectangle with a grid and the 'active' cells are yellow rectangles).

And the last concept we need is a Controller, here implemented as GameOfLifeController.
This class just glues together the model and the view.

So far my Game Of Life. The extra classes I've developed are used now in other board games that I'm developing.

Rules of the game :

Click on a gray rectangle to activate a cell, click on a yellow rectangle to deactivate it.

Press start to start the game