Grand Central Dispatch: First Look

September 6, 2009 | Filed Under Apple | No Comments

Mac OS X Grand Central DispatchIn the last years I’ve always used a “parallel task” approach foreach loops that I’ve in the code, not always to speedup but even to clean-up the code. How to do it? Wrapping threads and Thread Pool like in this C# Parallel Forech Code.

Snow Leopard has introduced a new BSD-level infrastructure, with simple and efficient API to do this job. Here a little usage preview.

Block objects are a C-based language feature that you can use in your C, Objective-C, and C++ code. Blocks make it easy to define a self-contained unit of work. Blocks are something like Actions (delegate {}) in C#. Very useful to embed function in loops.

Blocks looks like a “private” function pointer, but you can access to the “parent” vars. (If you’re a Python coder, you’ve exactly the same thing).

/* Blocks in Python...
 * def main():
 *    a = 10
 *    def test(k):
 *        print a, k
 *    test(128)
 */
int main (int argc, const char *argv[]) {
  int a = 12;

  void (^test_block) (int) = ^(int k) {
    printf("A Block: PARENT(%d) ARG(%d)\n", a, k);
  };

  test_block(128);

  return 0;
}

The GCD queue API provides dispatch queues from which threads take tasks to be executed. Because the threads are managed by GCD, Mac OS X can optimize the number of threads based upon available memory, number of currently active CPU cores, and so on. This shifts a great deal of the burden of power and resource management to the operating system itself, freeing your application to focus on the actual work to be accomplished.

#include <dispatch/dispatch.h>
#include <stdlib.h>
#include <stdio.h>

#define ITEM_VMIN       (1)
#define ITEM_VMAX       (200)
#define NR_ITEMS        (100)

static void __fill_item (void *items, size_t n) {
  int *i_items = (int *)items;
  i_items[n] = (ITEM_VMIN + (int)(ITEM_VMAX * ((double)rand() / RAND_MAX)));
}

static void __work_on_item (void *items, size_t n) {
  int *i_items = (int *)items;
  i_items[n] *= 100;  /* Do some Computation on this Item */
}

int main (int argc, const char *argv[]) {
  dispatch_queue_t queue;
  int data[NR_ITEMS];

  /* Get Global Dispatch Queue */
  queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

  /* Initialize data Elements, and run computation on each element */
  dispatch_apply_f(NR_ITEMS, queue, data, __fill_item);
  dispatch_apply_f(NR_ITEMS, queue, data, __work_on_item);

  /* Brief review of the items */
  dispatch_apply(NR_ITEMS, queue, ^(size_t n) {
    printf("Results: Item %lu = %d\n", n, data[n]);
  });

  return 0;
}

Mac OS X 10.6 Snow Leopard

September 5, 2009 | Filed Under Apple | No Comments

It’s finally here.  Mac OS X Snow Leopard, The world’s most advanced operating system. Finely tuned.

Mac OS X 10.6 Snow Leopard
Ok, It’s one week later… but I’ve installed it just right now. Maybe tomorrow morning an usage example of Grand Central Dispatch.

Cocoa: Sidebar with Badges, Take 2

March 8, 2009 | Filed Under Cocoa | 13 Comments

Cocoa SidebarDo you remember the Cocoa Sidebar? No, Take a Look at this post Cocoa Sidebar with Badges.

Joel asked me to revise the Sidebar, allowing to add/remove and do other operation at any time.

I’ve rewritten all the code of the Sidebar, and I’ve added a couple of new features, like the default action handler and obviously the ability to add, remove items and badges at any time.

All the past features, like Drag & Drop are still present, but there’s something else to do to improve it. If You’ve suggestions, patches or something else post a comment or send me a mail!

The Source Code is Available Here: Cocoa Sidebar 2 Source Code.

Update 10 March 2008 – Source Updated with Fixes.

Cocoa: Drag & Drop

February 28, 2009 | Filed Under Cocoa | 1 Comment

Today a simple example of Drag & Drop with Cocoa and NSView. The screenshot below shows two groups. In the first one, you can drop the photos on your filesystem, taken from Desktop or Finder. In the second group, you can only drop the first group image.

Cocoa Drag & Drop Test App

You can find the source code here: Drag & Drop Test Source Code.

WebKit: Google Maps

February 1, 2009 | Filed Under Cocoa | No Comments

Following the Google StreetView post, another example on How Cocoa Application can Interact with Google. Today the WebKit shows Google Maps.
Cocoa Google Maps - Aliso Viejo
Like iPhoto ‘09 you can select you Map Type (Terrain, Satellite, Hybrid) and you can Zoom In or Zoom Out using controls of your Application.
Cocoa Google Maps - Red Wood
You can Find the Source Code Here: Cocoa Google Maps.

WebKit: Google StreetView

January 17, 2009 | Filed Under Cocoa | 2 Comments

Last iPhoto ‘09 presented at MacWorld contains a couple of interesting Features: Faces and Places. Today, I’ve a little bit of free time to play with my Mac, and the topic is How to embed Google StreetView into a Cocoa Application.
Cocoa Streetview Cuppertino
The Solution is using WebKit and Google Maps API. We’ve a simple HTML file that contains StreetView “Canvas” and a couple of javascript methods that interact with GStreetviewPanorama Object.
Cocoa Streetview San Francisco
The Source Code is Available Here: Cocoa StreetView Source.

WebKit: Dynamic Content

December 6, 2008 | Filed Under Cocoa | No Comments

Today I’ve played a bit with WebKit. I Want do something like Cocoa VBox View and NSScrollView but with more flexibility. Below you can see the example result.

WebKit Dynamic Content

The interesting part of this example is How to manage WebKit content, and how to add something dynamically.

I use webView:decidePolicyForNavigationAction:request:frame:decisionListener: of WebPolicyDelegate Protocol to handle my custom requests, in this way…

- (void)webView:(WebView *)sender
    decidePolicyForNavigationAction:(NSDictionary *)actionInformation
   request:(NSURLRequest *)request frame:(WebFrame *)frame
   decisionListener:(id)listener
{
    if ([[[request URL] path] isEqualToString:@"PATH to Handle"]) {
        [listener ignore];
        // Handle Request
    } else {
         [listener use];
    }
}

…Then with a little bit of JavaScript I’ll set my dynamic content loaded from Database or somewhere else.

NSArray *args = [NSArray arrayWithObjects:@"Item1Content",
                                  @"Hi, I'm Test 1 Content", nil];
[[webKit windowScriptObject] callWebScriptMethod:@"fillElement"
                               withArguments:args];

The fillElement method is a simple JS function like this document.getElementById(elem).innerHTML = data;

Here you can find the Source Code.

Cocoa: Sidebar with Badges

December 2, 2008 | Filed Under Cocoa | 8 Comments

Yesterday, I’ve written a simple Sidebar controller that can saves you some time and trouble with Cocoa Source List. Nodes and Folders can be drag and dropped into other folders or near other items and you can easily set badges on nodes.

Cocoa Sidebar

Cocoa Sidebar

You can find the example Source Code Here.

And below you can see hot to add folders, nodes and set badges.

- (void)populateOutlineContents:(id)inObject {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  [sidebar addRootFolder:@"1" name:@"DEVICES"];
  [sidebar addChild:@"1.1" name:@"Machintosh HD"
               icon:[NSImage imageNamed:NSImageNameComputer]
             action:@selector(buttonPres:) target:self];

  [sidebar addRootFolder:@"2" name:@"PLACES"];
  [sidebar addChild:@"2.1"
                url:NSHomeDirectory()
             action:@selector(buttonPres:) target:self];

  [sidebar addRootFolder:@"3" name:@"OTHER."];
  [sidebar addChild:@"3.1" name:@"Bonjour"
               icon:[NSImage imageNamed:NSImageNameBonjour]
             action:@selector(buttonPres:) target:self];
  [sidebar addChild:@"3.2" name:@"Users"
               icon:[NSImage imageNamed:NSImageNameUserGroup]
             action:@selector(buttonPres:) target:self];

  [sidebar clearSelection];

  // Add Badge to Node with Key
  [sidebar setBadge:@"2.1" count:5];
  [sidebar setBadge:@"3.2" count:7];

  [pool release];
}

- (void)buttonPres:(id)sender {
  NSLog(@"Button Press %@", [sender nodeTitle]);
}
Next Page »