Tuesday, May 14, 2013

Hack Night: Conway's Game of Life

Domo had a "Mobile Hack Night" the other night.  I thought I'd slap-out a version of Conway's Game of Life.  I've always been fascinated by this simulation.

I started out with a simple implementation:
  • A LifeBoard class
    • you tell it the size of the game board
    • you call "tick" to advance to the next step in the game
  • A LifeView class
    • it creates a UIView per cell in the board
    • you call "changeViewBoard" to update every view to it's new state
Super simple.  And it worked -- really slowly.  So, out came instruments. And, I found the following:
  • [UIView viewWithTag:tag] is *really* slow with 100s of sub-views.  I created an NSDictionary of my 100s of subviews and kablam! That issue was gone!
  • I had used an NSDictionary in LifeBoard to store the state in.  I would create a key for a cell by [NSString stringWithFormat:@"%i.%i", x, y].  Another *super* slow idea.  Changed to [NSNumber numberWithInteger:(y * board.width + x)].  That was faster.
  • I then moved from an NSDictionary for storing the board to the following:
    • char* theBoard;
    • theBoard = (char*)malloc(width*height);
    • -(void)dealloc { free(theBoard); }
    • Now that is FAST.
The new-and-improved version runs ata reasonable frame rate, even at large board sizes (150x150 runs several frames a second).

Please see the upgraded code on GitHub.

Wednesday, May 8, 2013

Who is Dan?

I started writing code in 7th grade (Jr. High School or Middle School) in 1973.  Yes, that makes me really old.  I took to writing code like a fish to water -- I loved it and couldn't get enough time making things.  I primarily made games for fun, and utilities to help myself.  I remember writing a little program that helped me learn my spelling words.  This was in the day of a teletype, no monitor.

I have programmed professionally in the following languages and computers:
Data General - ASM
IBM PC - ASM, C++, Java
Macintosh - ASM
Amiga - ASM
Nintendo GameCube - C++
Dreamcast - C++
PlayStation - C
PlayStation 2 - C++
XBox - C++
Web - JavaScript
Web Servers - PHP, Java, Node.js
iOS (iPhone, iPad, iPod) - Objective C

I have programmed for fun (without making any money) on the following:
HP programmable calculator (moon lander)
TRS-80 - Basic, ASM, Fortran
Atari 800 - ASM
Apple ][ - ASM
PDP-11

I love to learn about programming -- new languages, new concepts, old concepts.  Writing down things I have discovered and used helps me remember, and hopefully helps others.

Xcode Shared Code

Shared Code for iOS

We all have multiple iPhone, iPad (iOS) apps that we are creating. We all have a collection of classes, methods and categories that we have become accustom to having access to.
Seems like there are a million ways to "share" code between multiple projects.  After days of research, I believe I have found THE way to share code between your many projects.

What I want is to have multiple apps that are all individual applications in their own source control repository.  I also want to have one (or more) source control repository that contains code that ALL my projects can use.  I want to be able to easily edit (fix bugs, add enhancements) the shared code while in the middle of working on one of my apps.

Here is what I ended up with:
/Users/myname/dev/app1
/Users/myname/dev/app2
/Users/myname/dev/app3
/Users/myname/dev/sharedLib
/Users/myname/dev/sharedLib2

Each of the above folders is a separate GitHub repo. (Yea!)

STEP 1:  Create my first library of shared code

  1. Create "sharedLib" Xcode project (You can name it anything you like)
    1. File | New | Project...
    2. Select "Framework and Library" under iOS
    3. Select "Cocoa Touch Static Library"
    4. "Next"
    5. Product Name: "sharedLib"
    6. (everything else should be filled out, like Organization Name, Use ARC ...)
    7. "Next"
    8. Select your folder where all your projects and shared libraries will live (/Users/myname/dev in my case)
    9. "Create"
  2. Click the "Run" button to build the library (which is empty for now)
  3. The "Library" of shared code exists and is ready to use in your "apps"
  4. For testing purpose, add at least 1 class to the library and re-build it

STEP 2: Prepare your library for easy use by other apps

  1. We will be using the default .h file that was created with your library as the "public access" to all classes, methods and categories in your library.
  2. Open the .m file that was created with your library ("sharedLib.m") and comment out the simple content.  Do the same with the .h file.
  3. #import your classes in the .h file (#import "MyFunctions.h")

STEP 3: Add the library into an app

  1. Either use an existing app, or create a new app (in Xcode, duh)
  2. I'll assume the app is in a sibling folder to the shared library project
  3. Open a Finder window to the library project
    1. Right+Click on any file in your library project and select "Show in Finder..."
  4. Close the Xcode project for the shared library (You can only have a project open "once", and when it is shared with an app, the library will be open.)
  5. Add the "sharedLib.xcodeproj" to your app
    1. Have Xcode and Finder both on the screen at the same time
    2. Drag the sharedLib.xcodeproj file onto Xcode
    3. Drop it in the project window, at the bottom (You should see a cute little blue line at the bottom of your project list, probably below below a folder named "Products")
    4. (If you already have a sub-project added to your project, you can drop the xcodeproj file on the top-item -- the actual project, the one in blue)

STEP 4: Configure you app to use your library

  1. Note: We still have your app open in Xcode, and the library is shown in the project window
  2. Add the library as a "Build Dependency"
    1. Select the project (top item in the window)
    2. Make sure the "TARGETS" window has the app selected
    3. Select "Build Phases"
    4. Expand "Target Dependencies (0 items)"
    5. Click "+" (to add a new dependency)
    6. You will see a tree with about 5 items shown
    7. Select the one near the bottom called "sharedLib" (not the "tests" version) with the house icon
    8. Click "Add"
  3. Add the library as a "Library"
    1. Still in the same spot as you were ("Build Phases")
    2. Expand "Link Binary with Libraries (3 items)"
    3. Click "+" (to add a new library -- your new library)
    4. At the top of the dialog, you should see "libsharedlib.a" -- select it
    5. Click "Add" (Note: it may show in red)
  4. Add the library as "Searchable Headers"
    1. Still in the same spot as you were ("Build Phases")
    2. Switch to "Build Settings"
    3. Make sure you have "All" selected (not "Basic")
    4. Scroll way down to "Search Paths" (it is about in the middle)
    5. Find "Header Search Paths"
    6. Double-Click on the right-hand-side of "Header Search Paths" row
    7. Click "+" to add a new search path
    8. Type:  ../sharedLib/sharedLib   (This is the *relative* path to the library code folder)
    9. Note: if you use sub-folders in your library, change "non-recursive" to "recursive"
  5. Set linker options
    1. Still in the same spot as you were ("Build Settings")
    2. Scroll down to "Linking" (a couple above "Search Paths")
    3. Find "Other Linker Flags" (about the middle of this section)
    4. Double-Click on the right-hand-side of "Other Linker Flags" row
    5. Click "+" to add a new linker flag
    6. Type: -ObjC
    7. Note: This option will make categories in your library available in your app

STEP 5: Code up your app

  1. #import "sharedLib.h" in your .pch of your app
  2. Code your app, build, run, repeat
  3. If, and when, needed: code in the library, build app, run, repeat
  4. Live happy
  5. Build another app using the exact same library
  6. Make millions

NOTES: