2014-01-07 11:25:07 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2008 Otto Chrons at Seastringo Oy.
|
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
|
|
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
2012-03-08 19:23:47 +08:00
|
|
|
|
|
|
|
#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
|
2012-04-19 14:35:52 +08:00
|
|
|
X:(UIAccelerationValue)ax
|
|
|
|
Y:(UIAccelerationValue)ay
|
|
|
|
Z:(UIAccelerationValue)az
|
2012-03-08 19:23:47 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
timestamp = aTimeStamp;
|
|
|
|
x = ax;
|
|
|
|
y = ay;
|
|
|
|
z = az;
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
2012-03-08 19:23:47 +08:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation UIAccelerometer (Simulation)
|
2012-08-21 05:08:49 +08:00
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
|
2012-03-08 19:23:47 +08:00
|
|
|
// override the static method and return our simulated version instead
|
|
|
|
+ (UIAccelerometer *)sharedAccelerometer
|
|
|
|
{
|
2013-06-21 08:46:22 +08:00
|
|
|
return [CCAccelerometerSimulation getAccelerometer];
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
2012-08-21 05:08:49 +08:00
|
|
|
#pragma clang diagnostic pop
|
2012-03-08 19:23:47 +08:00
|
|
|
@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
|
2013-06-21 08:46:22 +08:00
|
|
|
static CCAccelerometerSimulation *sharedAccelerometer = NULL;
|
2012-03-08 19:23:47 +08:00
|
|
|
|
2013-06-21 08:46:22 +08:00
|
|
|
@implementation CCAccelerometerSimulation
|
2012-03-08 19:23:47 +08:00
|
|
|
|
2012-08-24 04:41:54 +08:00
|
|
|
- (void) dealloc {
|
|
|
|
if (sharedAccelerometer) {
|
|
|
|
[sharedAccelerometer release];
|
|
|
|
sharedAccelerometer = NULL;
|
|
|
|
}
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2012-03-08 19:23:47 +08:00
|
|
|
// this is straight from developer guide example for multi-threaded notifications
|
|
|
|
- (void) setUpThreadingSupport {
|
|
|
|
if ( notifications ) return;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2012-03-08 19:23:47 +08:00
|
|
|
notifications = [[NSMutableArray alloc] init];
|
|
|
|
notificationLock = [[NSLock alloc] init];
|
|
|
|
notificationThread = [[NSThread currentThread] retain];
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2012-03-08 19:23:47 +08:00
|
|
|
notificationPort = [[NSMachPort alloc] init];
|
|
|
|
[notificationPort setDelegate:self];
|
|
|
|
[[NSRunLoop currentRunLoop] addPort:notificationPort
|
2012-04-19 14:35:52 +08:00
|
|
|
forMode:(NSString *) kCFRunLoopCommonModes];
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2012-04-19 14:35:52 +08:00
|
|
|
NSDate* date = [[NSDate alloc] init];
|
2012-03-08 19:23:47 +08:00
|
|
|
[notificationLock lock];
|
|
|
|
[notifications addObject:notification];
|
|
|
|
[notificationLock unlock];
|
|
|
|
[notificationPort sendBeforeDate:date
|
2012-04-19 14:35:52 +08:00
|
|
|
components:nil
|
|
|
|
from:nil
|
|
|
|
reserved:0];
|
|
|
|
[date release];
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-04-19 14:35:52 +08:00
|
|
|
// now we are in the main thread
|
2012-03-08 19:23:47 +08:00
|
|
|
// Process the notification here;
|
2012-04-19 14:35:52 +08:00
|
|
|
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];
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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];
|
|
|
|
}
|
2012-08-24 04:41:54 +08:00
|
|
|
#ifndef __clang_analyzer__
|
2013-06-21 08:46:22 +08:00
|
|
|
+ (CCAccelerometerSimulation *)getAccelerometer
|
2012-03-08 19:23:47 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
if( sharedAccelerometer == NULL )
|
2013-06-21 08:46:22 +08:00
|
|
|
sharedAccelerometer = [[CCAccelerometerSimulation alloc] initialize];
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
return sharedAccelerometer;
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
2012-08-24 04:41:54 +08:00
|
|
|
#endif
|
2012-03-08 19:23:47 +08:00
|
|
|
- (void)threadLoop:(id)object
|
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// initialize our version of the accelerometer
|
2013-06-21 08:46:22 +08:00
|
|
|
- (CCAccelerometerSimulation *)initialize
|
2012-03-08 19:23:47 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
accObject = [UIAccelerationSimulation alloc];
|
|
|
|
isExiting = false;
|
|
|
|
|
2012-09-16 05:19:14 +08:00
|
|
|
// couldn't get the CFSocket version to work with UDP and runloop, so used Berkeley sockets and a thread instead
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
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;
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// we grab the delegate setting action
|
|
|
|
- (void)setDelegate:(id<UIAccelerometerDelegate>)delegate
|
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
accelDelegate = delegate;
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
- (id<UIAccelerometerDelegate>)delegate
|
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
return accelDelegate;
|
2012-03-08 19:23:47 +08:00
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
#endif
|