InnoDB status, altering table by dropping foreign key column

So if you have a table, say Kinerja, that has a foreign key column, say NIP. And you need to alter that table by dropping the column, you can't just do:

alter table Kinerja drop column NIP;

It will spit errno 150 at ya.

You need to first drop the foreign key constraint pertinent to the said column, such as:

alter table Kinerja drop foreign key the_constraint_of_NIP_column_here;

After that is done, you can do:

alter table Kinerja drop column NIP;

But how to get the constraint? Well, just do:

alter table Kinerja drop column NIP;

first to get error. And then, look up the innoDB log by issuing:

show engine innoDB status;

In the log, find this paragraph:


------------------------
LATEST FOREIGN KEY ERROR
------------------------
121211  0:16:23 Error in foreign key constraint of table penilaian/kinerja:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
  CONSTRAINT "kinerja_ibfk_2" FOREIGN KEY ("NIP") REFERENCES "dosen" ("NIP")


There, you have the constraint! :p

Then, do delete the constraint and then the column.

Playing video with cocos2d


  1. Download cocos2d extension from: https://github.com/cocos2d/cocos2d-iphone-extensions
  2. Unzip, navigate into the directory: extensions -> CCVideoPlayer.
  3. Copy file CCVideoPlayer.h and CCVideoPlayer.m and the folder iOS. 
  4. Insert them anywhere in the project.
  5. In CCVideoPlayer.m, comment out the line #import "CCVideoPlayerImplMac.h"
  6. Done! To play video, simply do: [CCVideoPlayer playMovieWithFile:@"filename.mp4"]
  7. You can set a delegate to the CCVideoPlayer by implementing protocol: <CCVideoPlayerDelegate>
  8. The protocol will call method: 
    -(void) movieStartsPlaying
    when the movie starts
    and
    -(void) moviePlaybackFinished
    when the movie finishes.

Find the total force when two fixtures collide

contact->GetManifold().localPoint.Length()

Remove CCNode from parent after a sequence of actions

P.S:
Well, P here stands for Pre instead of Post, I guess. The following cocos2d discussion was started 3 years ago. Now I realize that there is a method: [CCNode removeFromParent]

So a useful post from cocos2d forum: http://www.cocos2d-iphone.org/forum/topic/981



I have some sprites and labels on the Layer. Before removing them they must do some actions (fade out for example). But after that I need to remove them from the layer with using [self removeChild:child cleanup:YES]. For that I create classes AutoCleaningSprite and AutoCleaningLabel which inherit Sprite and Label class and have new method:
- (void) removeFromParent{
CocosNode *parent=self.parent;
[parent removeChild:self cleanup:YES];
}
So for removing this objects after animation I used next actions:
[someAutoCleaningSprite runAction:
[Sequence actions:[FadeOut actionWithDuration:0.5],
[CallFunc actionWithTarget:someAutoCleaningSprite selector:@selector(removeFromParent)],nil]];
Is it correct method? Or may be there is something more simple way for removing CocosNode objects from the parent Object?
And I have another question - is it need to invoke [sprite release]; after [self removeChild:sprite cleanup:YES];?
Thanks..
Answer:


re:
(void) removeFromParent{
CocosNode *parent=self.parent;
[parent removeChild:self cleanup:YES];
}
This strategy will work and I've found it very useful on my projects but one thing anyone who tries it needs to be aware of is a really really really evil memory bug that gets caused unless your careful. First off, the solution:
CocosNode *parent=self.parent;
[self retain];
[parent removeChild:self cleanup:YES];
[self autorelease];
Huge hack I know, and there are cleaner ways to do this but what happens if you don't is total heisenbuggery. Background:
- The NSInvocation object associated with the CallFunc action wants to write a 'return value' to an address in the NSInvocation object ... even if your function doesn't return anything.
- When you call removeChild:self cleanup:YES your sprites ref count goes down by one
- If your sprites ref count just hit zero (as it probably will), instead of being released 'at some time in the future' its going to get deallocated NOW. Thank apple for that little bit of magic they do when removing objects from NSArrays
- That deallocation cascades to the Action and then the NSInvocation all before your function returns.
If you've got anything else going on (other threads for instance that may be allocating something ... I'm looking at you OpenFeint) the NSInvocation return is about to write on some memory that no longer belongs to it ... and you will likely not find out about it until way past too late ;)

Check whether a string contains substring.

Turns out that the Foundation Framework does not have this nifty little utility to check whether a string contains a substring. But this can be easily done manually:


-(BOOL)string:(NSString*)string1 containsString:(NSString*)string2{
    NSRange rangeValue = [string1 rangeOfString:string2 options:NSCaseInsensitiveSearch];
    if (rangeValue.length > 0){
        return TRUE;
    }
    else {
        return FALSE;
    }
}

Manual OpenGL draw on CCNode

Every point must be multiplied by     CC_CONTENT_SCALE_FACTOR();

Otherwise, the drawing will not be correctly placed on the screen!

XCode fails to launch app on the device

So I hit the run button to run the app on the device, but instead of running on the device, I got this dialog:


XCode failed to run my app on my device. I checked my device: the app is uploaded alright, and when I clicked it, it ran well. But why did XCode give me that fail dialog?

I did the following to fix:

1. Go to the dir mentioned in the dialog. Delete the app directory (OpenGLES_Ch2_.....)
2. Delete the uploaded app on the device
3. Restart XCode.

And everything went fine again.

Android SDK update

Updating Android SDK via Eclipse interface requires that your internet connection be stable. If in the middle of the download your connection is interrupted, you have to start over.
Yet, you can actually use download manager (which cache files and resume download from where you left off) when downloading SDK. Here's how:

Inspect the log window when you start the Android SDK Manager (it's the paper icon next to the tiny red square button). In the log, you can find the XML containing information about your download. Inspect the XML, and download whatever part of the SDK that you need.

Rooting Galaxy W

So here was my situation.

I got Galaxy W. Unrooted. Android Gingerbread 2.3.6. I needed to tinker with the new Google ADK. Google ADK, with the Android device acting as the USB accessory, require that Android 2.3.4 be installed as the minimum.
But then again, not all Android device with 2.3.4 version support USB accessory function. There has to be a certain file in the Android file system for it to support ADK. And my Galaxy W does not have it.
I could install those files manually but I needed to have root access on my Android. I needed to root my phone.

Here's how:

http://forum.xda-developers.com/showthread.php?t=1317394

1. Download this Zip-file copy this into the internal SD card.

2. While switched off, keep the following buttons pressed. Release the power-button once the Samsung Galaxy W(I8150) is switched on.


As soon as you see the Android with the box, release the Home- and Volume Up-button.

After you hit the menu-button shown on the last image, the screen will gray out, you will have to wait until the recovery menu appears.

3. Navigate with the volume up and down to apply sdcard:update.zip in Recovery Menu. To confirm your selection use the home-button.

4. Choose (with volume buttons) the update.zip file on your internal sd card and confirm again with Home-button. You will have to wait 5 seconds.

5. Now choose reboot system now and confirm with home button.

Now you device should be rooted.

Just in the case the website goes down or disappear for some reason, I copy it here. I got the zip file too, in case you need it.

When you do adb shell and get into Android file system, you can now do: su and get root privilege. But there are many commands which are not available on standard Android installation. One very important command missing being: cp. The copy command. Solution: install busybox. Copy the file into sdcard. Now everytime you want to execute copy, you can do: busybox cp ....

One more thing, before you can copy files to the system directory, you need to mount it as RW.

mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system

That's it!

How to clone Android repo

mkdir android 
cd android
repo init -u git://android.git.kernel.org/platform/manifest.git 
repo sync
make

http://twitter.com/Arubin/status/27808662429

Problem with Sprite Helper, Level Helper, Interlaced PNG

So....
I have this project in which I use @vladubogdan's Level Helper and Sprite Helper. Then I get this extremely annoying bug that I can't figure out the root:
If I run it on device the first time, the pictures are showing. Second time, not showing, third time showing, etc. WHAT HAS GONE WRONG?
Then I tried to clear the project and re build and I got this:


CopyPNGFile /Users/firman/Library/Developer/Xcode/DerivedData/Dotugov2-fhgqwfonumwjtachcdehbmsgrfdu/Build/Products/Debug-iphoneos/Dotugov2.app/timeselect-hd.png Dotugov2/Resources/Images/timeselect-hd.png
    cd /Users/firman/Documents/ios-project/Dotugov2
    setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/PrivatePlugIns/iPhoneOS Build System Support.xcplugin/Contents/Resources/copypng" -compress "" /Users/firman/Documents/ios-project/Dotugov2/Dotugov2/Resources/Images/timeselect-hd.png /Users/firman/Library/Developer/Xcode/DerivedData/Dotugov2-fhgqwfonumwjtachcdehbmsgrfdu/Build/Products/Debug-iphoneos/Dotugov2.app/timeselect-hd.png


While reading /Users/firman/Documents/ios-project/Dotugov2/Dotugov2/Resources/Images/timeselect-hd.png pngcrush caught libpng error:
   \341\217


While reading /Users/firman/Documents/ios-project/Dotugov2/Dotugov2/Resources/Images/timeselect-hd.png pngcrush caught libpng error:


I googled and arrived here: 


It says that the such error is caused by interlaced PNG images. I tried to resave the PNG images to non interlaced but to no avail. I don't know what to do next...

Small notes

Some lessons I learnt the past few days:

Cocos2D: Don't load heavy resources in the init method. This will crash the app. Instead, load them in a scheduled method.
Box2D: Don't change scene while world is locked (when detecting and responding to touch). This will cause a memory leak. Instead, change the scene in an scheduled method.
Android: The method insert in SQLiteDatabase doesn't throw exception. It does throw exception and print the stack trace but it's internally handled by that method and the exception won't by caught by the try catch block. If you need to catch exception, use insertOrThrow instead.

Code snippet to pad numbers with zero:

        NSString *paddingFormat = [[NSString stringWithFormat:@"time\n%%0%dd:%%0%dd", 2, 2] retain];
        NSString *paddedNumber = [NSString stringWithFormat:paddingFormat, 0, 0];

Result:

time
00:00

Hiero. Bitmap Font Tool

So I needed bitmap font atlas for my game. Bitmap font atlas is something similar to Image Atlas, only for font.

There's an open source code for it. The Slick project http://slick.cokeandcode.com/ The bitmap font tool is part of the project, which is located in the Hiero directory.

To correctly set it up as Eclipse project:

1. Create new Eclipse project. Copy the Hiero directory of the Slick project into the source directory of the new project.
2. Copy the lwgl.jar and lwgl-util.jar and slick.jar into the lib directory.
3. Copy the native (platform dependent) binary into some directory in the project structure.
4. Properties -> Java build path -> libraries then click on lwgl.jar and double click on native library location and in the resulting dialog, navigate to the directory where you saved the native binaries of lwgl for your platform.
5. Run the Hiero.java as Java application.

Or, if you still get errors or those steps are too much hassle, you can buy Glyphdesigner for USD 30. Glyphdesigner is better (not much better, just better) than Hiero, and it's easy to run and understand.

Correcting gravity of Box2D for portrait mode


In the accelerometer function of HelloWorldLayer.mm the gravity is set with this line
b2Vec2 gravity( -accelY * 10, accelX * 10);
In order to simulate the desired effect in portrait mode, the line must be re-ordered to:
b2Vec2 gravity( accelX * 10, accelY * 10);

Enabling telnet server on Mac

Is telnet still relevant? It turns out that the answer is yes. Recently a client commissioned me to develop a telnet client for Android. He's developing a wireless barcode scanner which connects to the server using telnet. To test my app, I needed to enable telnet server on my mac. Here's how I did it:

$ sudo launchctl load -w /System/Library/LaunchDaemons/telnet.plist

And to stop the server:


$ sudo launchctl unload -w /System/Library/LaunchDaemons/telnet.plist

How To Get Latitude and Longitude Coordinates from Google Maps

  1. Method one involves the use of a simple snippet of code in your browser's address bar.
  2. Find the location for which you would like to obtain coordinates in Google Maps.
  3. Right click on your chosen location, and select "center map here."
  4. Open Firebug's console in Firefox then copy and paste the snippet of javascript code below into the address bar, and hit "enter."
  5. javascript:void(prompt('',gApplication.getMap().getCenter()));
  6. This will activate a small pop-up window that will show the coordinates for the centered location in decimal format.
     
From: http://gps.about.com/od/gpsproductoverview/ht/google-maps-coordinates.htm

NIB files (or XIB files)

So, finally I got the hang of NIB files. I can now develop simple app either without the interface builder (pure code) or with interface builder (with NIB files).

I had always thought that a NIB file was always associated to a UIViewController. This was because when you create UIViewController, there is an option whether you want to create a NIB file for it or not. If you choose to create the associated NIB file, then the file owner of the NIB file will be set to the UIViewController class.

That was until I found this sample code from Apple: http://developer.apple.com/library/ios/#samplecode/Scrolling/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008023

In that sample code, the class of the file owner is UIApplication. It turns out that you can actually develop your app from scratch using the interface builder only (well, almost). You connect the NIB file (the main NIB file) to your application by setting the key "main NIB file base name" in your plist file to the value of your NIB file name (without the XIB extension). Contrast this with the practice of calling [UIViewController alloc] initWithNibFile] when you create a NIB file for a UIViewController.

Just remember to always set the file owner of your NIB file!

Cleaning up recorded URLs on Preview, QuickTime, etc.

There are times when I watched some dirty movies on Quicktime Mac or clicked on file with embarrassing name to show on Preview. Then the names of those files will be recorded by quicktime and preview, and when I click and hold on the preview icon on the tray, those embarrasing names will show up. After wading thru the Mac file system I finally found what I should delete to remove those names:

Go to /Users//Library/Preferences

In that folder, delete the file com.apple.


NB: Mac OS X Lion.

Objective C Memory Management

I found two concise but complete references online:
http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/MemoryMgmt.html
http://interfacelab.com/objective-c-memory-management-for-lazy-people/
http://www.raywenderlich.com/2657/memory-management-in-objective-c-tutorial

I will summarize them here to reinforce my understanding:

  1. If you do alloc + init or new (which is basically just a shortcut for alloc + init), you must subsequently call release.
  2. After you call release, you should set the var name to nil. So: [someVar release], and then someVar = nil; This is considered good practice (at least by Ray Wenderlich), because sending message to a nil var does nothing, while sending message to a deallocated var causes EXC_BAD_ACCESS.
  3. If you get a var from framework methods, then there's this convention:
    • If the method name begins with init or copy, the object returned will have a retain count of 1, and no autorelease pending. In other words, you own that object and have to release it when you’re done.
    • If the method name begins with anything else, the object returned will have a retain count of 1, and an autorelease pending. In other words, you can use the object right now, but if you want to use it later you have to retain the object.
  4. More about property, here's a snapshot of The Elements sample code:

    // Set up the portraitWindow and content view
    UIWindow *localPortraitWindow;
    localPortraitWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.portraitWindow = localPortraitWindow;

    // the localPortraitWindow data is now retained by the application delegate
    // so we can release the local variable
    [localPortraitWindow release];

    Lesson: when you retain a property, you increment its ref count. So you need to release accordingly.
  5. Do this:
    -(NSImage *)getAnImage {

    return [[[NSImage alloc] initWithContentsOfFile:@"/tmp/youownthis.jpg"] autorelease];

    }
    Instead of this:
    -(NSImage *)getAnImage {

    return [[NSImage alloc] initWithContentsOfFile:@"/tmp/youownthis.jpg"];

    }
    The caller will then have to retain the returned object, and subsequently release it.
Now, on the topic of XCode profile -> leaks tool. I made a curious discovery. I build a skeleton table view app, just a navigation controller and a root view controller. Without any string occupying any table cell. And then I ran the profiler with leaks template. I randomly clicked on the table, and I pulled the table up and release it and pull it down and release it and I did it multiple times. And it red bold lines showed up! UIKit framework is leaking memory!

Even the official The Elements sample code from Apple website is leaking memory when tested this way.

Nifty Mac commands

Some nifty commands that I use often on other platforms but I miss on Mac. After googling around, I found the Mac equivalents.

Showing the desktop: Cmd+Option and then click on desktop.

Taking snapshot:

  • Command-Shift-3: Take a screenshot of the screen, and save it as a file on the desktop
  • Command-Shift-4, then select an area: Take a screenshot of an area and save it as a file on the desktop
  • Command-Shift-4, then space, then click a window: Take a screenshot of a window and save it as a file on the desktop
  • Command-Control-Shift-3: Take a screenshot of the screen, and save it to the clipboard
  • Command-Control-Shift-4, then select an area: Take a screenshot of an area and save it to the clipboard
  • Command-Control-Shift-4, then space, then click a window: Take a screenshot of a window and save it to the clipboard 
Pre compiled binary for the famous wget Linux util:

https://techtach.s3.amazonaws.com/files/wget

I will keep this list updated.

Java Home on Mac

The shortest symlink to Java home (pointing to where the JDK is installed) is:

/Library/Java/Home

To set the JAVA_HOME env var:

export JAVA_HOME=/Library/Java/Home

But that only applies for the current session. To persist it, add it as entry in ~/.profile. Check that it's set:

echo $JAVA_HOME

Install Apache, PHP and MySQL on Mac OS Lion

I found this link, but it is for Snow Leopard, and I found the first part did not apply to me: in Lion, to enable Apache you must go to System Preference -> Sharing -> Web Sharing.
Enable web sharing, which will enable Apache, and you can also see there the IP to access your computer (I found out that 127.0.0.1 or localhost did not work).

And the rest, just follow the instruction there. I copy here:

PHP

In /etc/apache2/httpd.conf, uncomment this line:

LoadModule php5_module libexec/apache2/libphp5.so

Restart Apache

sudo apachectl restart

Fix a warning appearing in phpinfo()

Create /etc/php.ini and make it writable

cd /etc
sudo cp php.ini.default php.ini
sudo chmod 666 php.ini

In php.ini, find this line:

;date.timezone =

Uncomment it and insert your time zone (http://php.net/manual/en/timezones.php)

date.timezone =America/Vancouver

Restart Apache

sudo apachectl restart

MySQL

Download the MySQL package for Mac OS X.5 (32 or 64 bits depending on your machine)
Install everything in the package in this order: mysql, the startup item, the preference pane.
Start MySQL in the preference pane.
Test it's working:

/usr/local/mysql/bin/mysql

Fix mysql.sock location in php.ini

In /etc/php.ini, replace the three occurences of /var/mysql/mysql.sock by /tmp/mysql.sock

pdo_mysql.default_socket=/tmp/mysql.sock
mysql.default_socket = /tmp/mysql.sock
mysqli.default_socket = /tmp/mysql.sock

Restart Apache

sudo apachectl restart

Extra
Activate PHP short tags

In /etc/php.ini, under Language Options, change

short_open_tag = Off

to

short_open_tag = On

Restart Apache

sudo apachectl restart

Generating random number between a range

So, might be old trick but I find it useful to record here:

Min + (int)(Math.random() * ((Max - Min) + 1))