Mumbling About UIAccelerometer, CoreMotion, Availability, and Block Type

I'm still tinkering with Ogre3D, especially Object-Oriented Input System (OIS) part. This is a cross-platform library providing the same input handling interface to devices such as keyboard, mouse, joystick, touchscreen, accelerometer for various OSs.

Though, it seems original OIS library is a bit falling behind the pace: OIS code maintained by Ogre3D dev community is more polished (OgreDeps).

So I spent last evening merging changes made to OgreDeps into OIS code, and updated Xcode template in OIS to properly compile (though I have to put ConsoleDemo aside for well known Carbon's disability to commingle with 64-bit code). Xcode has a nice (yet with a little lame GUI, but working) dev tool called FileMerge, this will help when you want to compare a file or directory tree with another.

Before going to sleep, I read various stuff related to Apple's CoreMotion framework scattered across the web, intended to replace deprecated UIAccelerometer code part in OIS with CoreMotion code.

And this morning, with Availability.h's OS version check macro, I updated the code. 

Now, the code is aware of whether or not the minimum required iOS version is more than or equal to 4 (CoreMotion's accelerometer functionality is available since iOS 4). If the minimum iOS version requirement is not met, source code is compiled against old code with UIAccelerometer, and is compiled against new code with CoreMotion's accelerometer handling mechanics otherwise.
The following is a code snippet, I wont put all lengthy updated iOS code of OIS. But I think you can get the point:

PhoneAccelerometer::iPhoneAccelerometer( InputManager* creator, bool buffered )
: JoyStick(creator->inputSystemName(), buffered, 0, creator)
    iPhoneInputManager *man = static_cast<iPhoneInputManager*>(mCreator);
    [man->_getDelegate() setAccelerometerObject:this];
    [[UIAccelerometer sharedAccelerometer] setDelegate:man->_getDelegate()];
    manager = [[CMMotionManager alloc] init];
    didAccelerate = ^(CMAccelerometerData *data, NSError *error) {
        // where should it go?
        // data.timestamp;
        mTempState.x = data.acceleration.x;
        mTempState.y = data.acceleration.y;
        mTempState.z = data.acceleration.z;
    [manager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:didAccelerate];
    mUpdateFrequency = 60.0f;

Looking into OIS code, I had impression that explicit delegate/handle/callback functions are used often for registering user defined functions in old time (like in iOS 1 & 2), and I also imagined that with introduction of Apple's C language extension, Block type, trend of defining delegate/handle/callback functions in OS X/iOS dev environment moved to implicit, anonymous functions.

If you don't know what is "block type," then try compiling the following in Xcode with Command Line template:

#include <iostream>

int main()
    void (^block_func)(std::string) = ^(std::string msg)
        std::cout << msg << std::endl;
    block_func("Hello World!");

Then, if you have GCC other than provided by Apple, such as installed with MacPorts /opt/local/bin/g++-mp-4.8, try compiling the above code with it; it will complains with errors.

When I first know existence of block type without knowing its origin, I really enjoyed it. Then revelation: it's a C extension by Apple and cannot be used in other compilers; I ewwed, really ewwed. But I didn't recognized full potential of lambda expression, closure and likes at that time; I know this kind of functionality is really helpful.


Popular posts from this blog

Hardcoding Data Like Images and Sounds into HTML or CSS

DDS for GIMP (Mountain Lion, Native, no X11 GUI)

Make It Work: Global .gitattributes