mirror of https://github.com/axmolengine/axmol.git
239 lines
6.4 KiB
Objective-C
239 lines
6.4 KiB
Objective-C
//
|
|
// AccelerometerSimulation.m
|
|
// AccelerometerGraph
|
|
//
|
|
// Created by Otto Chrons on 9/26/08.
|
|
// Copyright 2008 Seastringo Oy. All rights reserved.
|
|
//
|
|
|
|
#import "AccelerometerSimulation.h"
|
|
|
|
// when compiling to ARM (iPhone device), hide everything and use system defaults
|
|
// if you wish to use simulation mode even on the device, remove the #if/#endif
|
|
#if !TARGET_CPU_ARM
|
|
|
|
#import <netdb.h>
|
|
|
|
#define kAccelerometerSimulationPort 10552
|
|
|
|
@implementation UIAccelerationSimulation
|
|
|
|
@synthesize timestamp;
|
|
@synthesize x;
|
|
@synthesize y;
|
|
@synthesize z;
|
|
|
|
-(UIAccelerationSimulation*)initWithTimestamp:(NSTimeInterval)aTimeStamp
|
|
X:(UIAccelerationValue)ax
|
|
Y:(UIAccelerationValue)ay
|
|
Z:(UIAccelerationValue)az
|
|
{
|
|
timestamp = aTimeStamp;
|
|
x = ax;
|
|
y = ay;
|
|
z = az;
|
|
|
|
return self;
|
|
}
|
|
@end
|
|
|
|
@implementation UIAccelerometer (Simulation)
|
|
|
|
// override the static method and return our simulated version instead
|
|
+ (UIAccelerometer *)sharedAccelerometer
|
|
{
|
|
return [AccelerometerSimulation getAccelerometer];
|
|
}
|
|
@end
|
|
/*
|
|
// callback that never got called with CFSocket UDP...
|
|
|
|
void mySocketCallBack( CFSocketRef s,
|
|
CFSocketCallBackType callbackType,
|
|
CFDataRef address,
|
|
const void *data,
|
|
void *info)
|
|
{
|
|
AccelerometerSimulation *accSim = (AccelerometerSimulation*)info;
|
|
|
|
NSLog(@"Data %s received", (char*)data);
|
|
}
|
|
*/
|
|
|
|
// singleton
|
|
static AccelerometerSimulation *sharedAccelerometer = NULL;
|
|
|
|
@implementation AccelerometerSimulation
|
|
|
|
// this is straight from developer guide example for multi-threaded notifications
|
|
- (void) setUpThreadingSupport {
|
|
if ( notifications ) return;
|
|
|
|
notifications = [[NSMutableArray alloc] init];
|
|
notificationLock = [[NSLock alloc] init];
|
|
notificationThread = [[NSThread currentThread] retain];
|
|
|
|
notificationPort = [[NSMachPort alloc] init];
|
|
[notificationPort setDelegate:self];
|
|
[[NSRunLoop currentRunLoop] addPort:notificationPort
|
|
forMode:(NSString *) kCFRunLoopCommonModes];
|
|
}
|
|
|
|
// this is straight from developer guide example
|
|
|
|
- (void) processNotification:(NSNotification *) notification {
|
|
if( [NSThread currentThread] != notificationThread ) {
|
|
// Forward the notification to the correct thread, this is the socket thread
|
|
NSDate* date = [[NSDate alloc] init];
|
|
[notificationLock lock];
|
|
[notifications addObject:notification];
|
|
[notificationLock unlock];
|
|
[notificationPort sendBeforeDate:date
|
|
components:nil
|
|
from:nil
|
|
reserved:0];
|
|
[date release];
|
|
}
|
|
else {
|
|
// now we are in the main thread
|
|
// Process the notification here;
|
|
NSString *data = (NSString*)[notification object];
|
|
|
|
// parse the data, no error handling!
|
|
NSArray *components = [data componentsSeparatedByString:@","];
|
|
|
|
// create our own acceleration object
|
|
[accObject initWithTimestamp:[[components objectAtIndex:1] doubleValue]
|
|
X:[[components objectAtIndex:2] doubleValue]
|
|
Y:[[components objectAtIndex:3] doubleValue]
|
|
Z:[[components objectAtIndex:4] doubleValue]];
|
|
[accelDelegate accelerometer:self didAccelerate:(UIAcceleration*)accObject];
|
|
}
|
|
}
|
|
|
|
// this is straight from developer guide example
|
|
- (void) handleMachMessage:(void *) msg {
|
|
[notificationLock lock];
|
|
while ( [notifications count] ) {
|
|
NSNotification *notification = [[notifications objectAtIndex:0] retain];
|
|
[notifications removeObjectAtIndex:0];
|
|
[notificationLock unlock];
|
|
[self processNotification:notification];
|
|
[notification release];
|
|
[notificationLock lock];
|
|
};
|
|
[notificationLock unlock];
|
|
}
|
|
|
|
+ (AccelerometerSimulation *)getAccelerometer
|
|
{
|
|
if( sharedAccelerometer == NULL )
|
|
sharedAccelerometer = [[AccelerometerSimulation alloc] initialize];
|
|
|
|
return sharedAccelerometer;
|
|
}
|
|
|
|
- (void)threadLoop:(id)object
|
|
{
|
|
char buffer[1024];
|
|
// we never exit...
|
|
while(1) {
|
|
int count = recv( udpSocket, buffer, sizeof(buffer), 0 );
|
|
if( count > 0 )
|
|
{
|
|
// got data, let's pass it on
|
|
buffer[count] = 0;
|
|
NSString *str = [[NSString alloc] initWithUTF8String:buffer];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"ThreadAccelNotification" object:str];
|
|
[str release];
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// initialize our version of the accelerometer
|
|
- (AccelerometerSimulation *)initialize
|
|
{
|
|
accObject = [UIAccelerationSimulation alloc];
|
|
isExiting = false;
|
|
|
|
// couldn't get the CFSocket version to work with UDP and runloop, so used Berkely sockets and a thread instead
|
|
|
|
udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
struct sockaddr_in sin;
|
|
memset(&sin, 0, sizeof(sin));
|
|
// listen on all interfaces
|
|
sin.sin_addr.s_addr = INADDR_ANY;
|
|
sin.sin_len = sizeof(struct sockaddr_in);
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_port = htons(kAccelerometerSimulationPort);
|
|
|
|
bind(udpSocket, (const struct sockaddr*)&sin, sizeof(sin));
|
|
|
|
// create a separate thread for receiving UDP packets
|
|
thread = [[NSThread alloc] initWithTarget:self
|
|
selector:@selector(threadLoop:)
|
|
object:nil];
|
|
[thread start];
|
|
|
|
// cross-thread communication setup
|
|
[self setUpThreadingSupport];
|
|
[[NSNotificationCenter defaultCenter]
|
|
addObserver:self
|
|
selector:@selector(processNotification:)
|
|
name:@"ThreadAccelNotification"
|
|
object:nil];
|
|
/*
|
|
// create and initialize a socket
|
|
CFSocketContext ctx;
|
|
|
|
ctx.info = self;
|
|
ctx.version = 0;
|
|
ctx.retain = NULL;
|
|
ctx.release = NULL;
|
|
ctx.copyDescription = NULL;
|
|
udpSocket = CFSocketCreate(NULL, PF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketDataCallBack | 0xF, mySocketCallBack, NULL);
|
|
|
|
CFRunLoopSourceRef source;
|
|
CFDataRef addr;
|
|
CFSocketError theErr;
|
|
struct sockaddr_in sin;
|
|
memset(&sin, 0, sizeof(sin));
|
|
sin.sin_addr.s_addr = INADDR_ANY;
|
|
sin.sin_len = sizeof(struct sockaddr_in);
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_port = htons(10552);
|
|
addr = CFDataCreate(NULL, (unsigned char *)&sin, sizeof(sin));
|
|
theErr = CFSocketConnectToAddress(udpSocket, addr, 0);
|
|
switch (theErr) {
|
|
case kCFSocketSuccess:
|
|
NSLog(@"UDP Logged in");
|
|
source = CFSocketCreateRunLoopSource(NULL, udpSocket, 0);
|
|
CFRunLoopAddSource(CFRunLoopGetMain(), source,
|
|
kCFRunLoopDefaultMode);
|
|
break;
|
|
case kCFSocketError:
|
|
NSLog(@"UDP Error");
|
|
break;
|
|
default:
|
|
NSLog(@"UDP Networking Error");
|
|
break;
|
|
}
|
|
*/
|
|
return self;
|
|
}
|
|
|
|
// we grab the delegate setting action
|
|
- (void)setDelegate:(id<UIAccelerometerDelegate>)delegate
|
|
{
|
|
accelDelegate = delegate;
|
|
}
|
|
|
|
- (id<UIAccelerometerDelegate>)delegate
|
|
{
|
|
return accelDelegate;
|
|
}
|
|
@end
|
|
|
|
#endif
|