mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// ControlComponent.h
|
||||
// IOSClient
|
||||
//
|
||||
// Created by Ben Tkacheff on 9/6/12.
|
||||
// Copyright (c) 2012 tolkring@gmail.com. All rights reserved.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#include "v8datamodel/UserInputService.h"
|
||||
#include "v8datamodel/GamepadService.h"
|
||||
#include "v8datamodel/TouchInputService.h"
|
||||
|
||||
@class ControlView;
|
||||
|
||||
@interface ControlComponent : UIImageView
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (RBX::Game*) getGameFromControlView;
|
||||
- (RBX::GamepadService*) getGamepadServiceForGameDataModel;
|
||||
- (RBX::UserInputService*) getUserInputServiceForGameDataModel;
|
||||
- (RBX::TouchInputService*) getTouchInputServiceForGameDataModel;
|
||||
|
||||
- (ControlView*) findControlView;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// ControlComponent.m
|
||||
// IOSClient
|
||||
//
|
||||
// Created by Ben Tkacheff on 9/6/12.
|
||||
// Copyright (c) 2012 tolkring@gmail.com. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ControlComponent.h"
|
||||
#import "ControlView.h"
|
||||
|
||||
#include "v8datamodel/TouchInputService.h"
|
||||
|
||||
@implementation ControlComponent
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
self.userInteractionEnabled = true;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (ControlView*) findControlView
|
||||
{
|
||||
if ([self isKindOfClass:[ControlView class]])
|
||||
return (ControlView*)self;
|
||||
|
||||
id nextSuperView = self.superview;
|
||||
|
||||
while (nextSuperView != nil)
|
||||
{
|
||||
if ([nextSuperView isKindOfClass:[ControlView class]])
|
||||
return nextSuperView;
|
||||
|
||||
if ([nextSuperView isKindOfClass:[UIView class]])
|
||||
{
|
||||
UIView* theUIView = nextSuperView;
|
||||
nextSuperView = theUIView.superview;
|
||||
}
|
||||
else
|
||||
nextSuperView = nil;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(RBX::Game*) getGameFromControlView
|
||||
{
|
||||
ControlView* controlView = [self findControlView];
|
||||
if (controlView == nil)
|
||||
return nil;
|
||||
|
||||
return [controlView getGame].get();
|
||||
}
|
||||
|
||||
- (RBX::GamepadService*) getGamepadServiceForGameDataModel
|
||||
{
|
||||
if (RBX::Game* game = [self getGameFromControlView])
|
||||
if (shared_ptr<RBX::DataModel> currDataModel = game->getDataModel())
|
||||
return RBX::ServiceProvider::create<RBX::GamepadService>(currDataModel.get());
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (RBX::UserInputService*) getUserInputServiceForGameDataModel
|
||||
{
|
||||
if (RBX::Game* game = [self getGameFromControlView])
|
||||
if (shared_ptr<RBX::DataModel> currDataModel = game->getDataModel())
|
||||
return RBX::ServiceProvider::find<RBX::UserInputService>(currDataModel.get());
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (RBX::TouchInputService*) getTouchInputServiceForGameDataModel
|
||||
{
|
||||
if (RBX::Game* game = [self getGameFromControlView])
|
||||
if (shared_ptr<RBX::DataModel> currDataModel = game->getDataModel())
|
||||
return RBX::ServiceProvider::create<RBX::TouchInputService>(currDataModel.get());
|
||||
|
||||
return nil;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// ControlView.h
|
||||
// IOSClient
|
||||
//
|
||||
// Created by Ben Tkacheff on 8/21/12.
|
||||
// Copyright (c) 2012 tolkring@gmail.com. All rights reserved.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "v8datamodel/UserInputService.h"
|
||||
#include "V8DataModel/TextBox.h"
|
||||
#include "v8datamodel/Game.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RbxInputView.h"
|
||||
|
||||
@interface ControlView : ControlComponent <UIGestureRecognizerDelegate>
|
||||
{
|
||||
RbxInputView* rbxInputView;
|
||||
|
||||
RBX::Vector2int16 frameSize;
|
||||
|
||||
UITouch* tapTouch;
|
||||
G3D::Vector2 tapTouchBeginPos;
|
||||
|
||||
double tapSensitivity;
|
||||
int tapTouchMoveTolerance;
|
||||
|
||||
boost::weak_ptr<RBX::Game> game;
|
||||
|
||||
rbx::signals::scoped_connection dmUserInputTextBoxFocusCon;
|
||||
rbx::signals::scoped_connection dmUserInputTextBoxReleaseFocusCon;
|
||||
rbx::signals::scoped_connection dmUserInputProcessMouseEventCon;
|
||||
|
||||
// fake mouse events (for backwards compatibility
|
||||
shared_ptr<RBX::InputObject> mouseButton1Event;
|
||||
shared_ptr<RBX::InputObject> mouseMoveEvent;
|
||||
}
|
||||
|
||||
- (id) init:(CGRect)frame withGame:(boost::shared_ptr<RBX::Game>) newGame;
|
||||
- (void) dealloc;
|
||||
|
||||
- (RbxInputView*) getRbxInputView;
|
||||
|
||||
- (void) disconnectEvents;
|
||||
- (void) setupEvents;
|
||||
|
||||
- (void) setGame:(boost::shared_ptr<RBX::Game>) newGame;
|
||||
- (boost::shared_ptr<RBX::Game>) getGame;
|
||||
|
||||
- (void) textBoxFocusGained:(boost::shared_ptr<RBX::TextBox>) textBoxFocused;
|
||||
- (void) textBoxFocusLost:(boost::shared_ptr<RBX::TextBox>) textBoxUnfocused;
|
||||
|
||||
|
||||
// Gesture Recognizers
|
||||
// Tap
|
||||
- (void) oneFingerSingleTap;
|
||||
- (UITouch*) checkTouchesForTap:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||
- (void) checkTapTouchMove:(NSSet*) touchesSet;
|
||||
- (void) invalidateTapGesture:(id) oldTapTouch;
|
||||
|
||||
- (void) postMouseEventProcessed:(bool) processedEvent inputObject: (void*) uiTouch event:(const shared_ptr<RBX::InputObject>&) event;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,312 @@
|
||||
//
|
||||
// ControlView.m
|
||||
// IOSClient
|
||||
//
|
||||
// Created by Ben Tkacheff on 8/21/12.
|
||||
// Copyright (c) 2012 tolkring@gmail.com. All rights reserved.
|
||||
//
|
||||
#import "ControlView.h"
|
||||
#import "GameKeyboard.h"
|
||||
#import "PlaceLauncher.h"
|
||||
#include "ObjectiveCUtilities.h"
|
||||
#import "RobloxNotifications.h"
|
||||
|
||||
@implementation ControlView
|
||||
|
||||
- (id) init:(CGRect)frame withGame:(boost::shared_ptr<RBX::Game>) newGame
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(gotStartLeaveGameNotification:)
|
||||
name:RBX_NOTIFY_GAME_START_LEAVING
|
||||
object:nil ];
|
||||
game = newGame;
|
||||
[self setupEvents];
|
||||
|
||||
// initial size has coordinates for height/width flipped, as it always returns portait mode, no matter our current orientation :(
|
||||
CGRect correctRect = CGRectMake(0,0,frame.size.height,frame.size.width);
|
||||
frameSize = RBX::Vector2int16(frame.size.height, frame.size.width);
|
||||
|
||||
// self initialization
|
||||
self.multipleTouchEnabled = YES;
|
||||
self.frame = correctRect;
|
||||
|
||||
[self setupInputControls];
|
||||
|
||||
mouseMoveEvent = RBX::Creatable<RBX::Instance>::create<RBX::InputObject>(RBX::InputObject::TYPE_MOUSEMOVEMENT,
|
||||
RBX::InputObject::INPUT_STATE_CHANGE,
|
||||
RBX::Vector3(-1,-1,0),
|
||||
RBX::Vector3(0,0,0),
|
||||
[self getGame]->getDataModel().get());
|
||||
|
||||
mouseButton1Event = RBX::Creatable<RBX::Instance>::create<RBX::InputObject>(RBX::InputObject::TYPE_MOUSEBUTTON1,
|
||||
RBX::InputObject::INPUT_STATE_BEGIN,
|
||||
RBX::Vector3(-1,-1,0),
|
||||
RBX::Vector3(0,0,0),
|
||||
[self getGame]->getDataModel().get());
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
-(void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
[[GameKeyboard sharedInstance] setParentView:nil];
|
||||
|
||||
rbxInputView = nil;
|
||||
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self];
|
||||
}
|
||||
|
||||
- (RbxInputView*) getRbxInputView
|
||||
{
|
||||
return rbxInputView;
|
||||
}
|
||||
|
||||
- (void) setGame:(boost::shared_ptr<RBX::Game>) newGame
|
||||
{
|
||||
game = newGame;
|
||||
if(boost::shared_ptr<RBX::Game> sharedGame = game.lock())
|
||||
{
|
||||
[self dataModelChanged:sharedGame->getDataModel().get()];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) gotStartLeaveGameNotification:(NSNotification *)aNotification
|
||||
{
|
||||
[self disconnectEvents];
|
||||
}
|
||||
|
||||
|
||||
-(void) dataModelChanged:(RBX::DataModel*) dataModel
|
||||
{
|
||||
if(dataModel)
|
||||
{
|
||||
[self setupEvents];
|
||||
[self setupInputControls];
|
||||
}
|
||||
else // we have a null datamodel, tear down connections
|
||||
[self disconnectEvents];
|
||||
}
|
||||
|
||||
- (void) postMouseEventProcessed:(bool) processedEvent inputObject: (void*) uiTouch event: (const shared_ptr<RBX::InputObject>&) event
|
||||
{
|
||||
if (uiTouch && processedEvent)
|
||||
{
|
||||
void* tapTouchPtr = (__bridge void*) tapTouch;
|
||||
if( uiTouch && (uiTouch == tapTouchPtr) )
|
||||
[self invalidateTapGesture:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) textBoxFocusGained:(boost::shared_ptr<RBX::TextBox>) textBoxFocused
|
||||
{
|
||||
if(textBoxFocused != NULL && textBoxFocused != boost::shared_ptr<RBX::TextBox>())
|
||||
[[GameKeyboard sharedInstance] showKeyboardWithTextBox: textBoxFocused];
|
||||
else
|
||||
[[GameKeyboard sharedInstance] showKeyboard: ""];
|
||||
}
|
||||
|
||||
- (void) textBoxFocusLost:(boost::shared_ptr<RBX::TextBox>) textBoxUnfocused
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[GameKeyboard sharedInstance] hideKeyboard];
|
||||
});
|
||||
}
|
||||
|
||||
- (boost::shared_ptr<RBX::Game>) getGame
|
||||
{
|
||||
return game.lock();
|
||||
}
|
||||
|
||||
- (void) setupEvents
|
||||
{
|
||||
if(boost::shared_ptr<RBX::Game> sharedGame = game.lock())
|
||||
{
|
||||
[self bindToUserInputService:sharedGame->getDataModel()];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) disconnectEvents
|
||||
{
|
||||
dmUserInputTextBoxFocusCon.disconnect();
|
||||
dmUserInputTextBoxReleaseFocusCon.disconnect();
|
||||
dmUserInputProcessMouseEventCon.disconnect();
|
||||
}
|
||||
|
||||
- (void) bindToUserInputService:(shared_ptr<RBX::DataModel>) dataModel
|
||||
{
|
||||
if( RBX::UserInputService* userInputService = RBX::ServiceProvider::find<RBX::UserInputService>(dataModel.get()) )
|
||||
{
|
||||
// code below will listen to UserInputService and detect when a textbox is in focus (so we can show the virtual keyboard)
|
||||
dmUserInputTextBoxFocusCon = userInputService->textBoxGainFocus.connect( boostFuncFromSelector_1< boost::shared_ptr<RBX::Instance> >
|
||||
(@selector(textBoxFocusGained:),self) );
|
||||
|
||||
dmUserInputTextBoxReleaseFocusCon = userInputService->textBoxReleaseFocus.connect( boostFuncFromSelector_1< boost::shared_ptr<RBX::Instance> >
|
||||
(@selector(textBoxFocusLost:),self) );
|
||||
|
||||
// code below will listen to UserInputService when it fires a mouse event post event (bool tells whether the mouse event was used by app)
|
||||
dmUserInputProcessMouseEventCon = userInputService->processedMouseEvent.connect( boostFuncFromSelector_3<bool, void*, const shared_ptr<RBX::InputObject>& >
|
||||
(@selector(postMouseEventProcessed:inputObject:event:),self) );
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setupInputControls
|
||||
{
|
||||
// how quickly (in seconds) a user has to tap the screen to have a mouse down/up gesture sent
|
||||
tapSensitivity = 0.19f;
|
||||
// how much a tap can move in pixels on screen
|
||||
tapTouchMoveTolerance = 20;
|
||||
|
||||
// Subview initialization
|
||||
CGRect correctRect = self.frame;
|
||||
|
||||
if(rbxInputView != nil)
|
||||
{
|
||||
[rbxInputView removeFromSuperview];
|
||||
rbxInputView = nil;
|
||||
}
|
||||
|
||||
rbxInputView = [[RbxInputView alloc] init:correctRect];
|
||||
[self addSubview:rbxInputView];
|
||||
[rbxInputView datamodelInit];
|
||||
|
||||
[[GameKeyboard sharedInstance] setParentView:self];
|
||||
}
|
||||
|
||||
- (void) invalidateTapGesture:(id) oldTapTouch
|
||||
{
|
||||
if(oldTapTouch)
|
||||
{
|
||||
if( oldTapTouch == tapTouch )
|
||||
tapTouch = nil;
|
||||
}
|
||||
else
|
||||
tapTouch = nil;
|
||||
}
|
||||
|
||||
-(UITouch*) checkTouchesForTap:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
if(tapTouch)
|
||||
{
|
||||
for(UITouch* touch in touches)
|
||||
{
|
||||
if(touch == tapTouch)
|
||||
{
|
||||
UITouch* retainTapTouch = tapTouch;
|
||||
[self oneFingerSingleTap];
|
||||
return retainTapTouch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
if (!tapTouch && [touches count] == 1)
|
||||
{
|
||||
tapTouch = [touches anyObject];
|
||||
CGPoint startPoint = [tapTouch locationInView:self];
|
||||
tapTouchBeginPos = G3D::Vector2(startPoint.x,startPoint.y);
|
||||
[self performSelector:@selector(invalidateTapGesture:) withObject:[touches anyObject] afterDelay:tapSensitivity];
|
||||
}
|
||||
|
||||
for (UITouch* touch in touches)
|
||||
{
|
||||
CGPoint currPoint = [touch locationInView:self];
|
||||
|
||||
mouseButton1Event->setInputState(RBX::InputObject::INPUT_STATE_BEGIN);
|
||||
mouseButton1Event->setPosition(RBX::Vector3(currPoint.x,currPoint.y,0));
|
||||
}
|
||||
}
|
||||
|
||||
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
UITouch* theTapTouch = [self checkTouchesForTap:touches withEvent:event];
|
||||
|
||||
for(UITouch* touch in touches)
|
||||
{
|
||||
CGPoint currPoint = [touch locationInView:self];
|
||||
|
||||
if(touch == theTapTouch)
|
||||
[self invalidateTapGesture:nil];
|
||||
else
|
||||
{
|
||||
mouseButton1Event->setInputState(RBX::InputObject::INPUT_STATE_END);
|
||||
mouseButton1Event->setPosition(RBX::Vector3(currPoint.x,currPoint.y,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[self checkTapTouchMove:touches];
|
||||
|
||||
for(UITouch* touch in touches)
|
||||
{
|
||||
CGPoint currPoint = [touch locationInView:self];
|
||||
|
||||
mouseMoveEvent->setPosition(G3D::Vector3(currPoint.x, currPoint.y, 0));
|
||||
}
|
||||
}
|
||||
|
||||
-(void) checkTapTouchMove:(NSSet*) touchesSet
|
||||
{
|
||||
for(UITouch* touch in touchesSet)
|
||||
{
|
||||
if(tapTouch == touch)
|
||||
{
|
||||
CGPoint tapTouchLocationCGPoint = [tapTouch locationInView:self];
|
||||
RBX::Vector2 tapTouchLocation = RBX::Vector2(tapTouchLocationCGPoint.x,tapTouchLocationCGPoint.y);
|
||||
if((tapTouchLocation - tapTouchBeginPos).length() > tapTouchMoveTolerance)
|
||||
[self invalidateTapGesture:nil];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
for(UITouch* touch in touches)
|
||||
{
|
||||
if(touch == tapTouch)
|
||||
{
|
||||
tapTouch = nil;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) oneFingerSingleTap
|
||||
{
|
||||
if(RBX::UserInputService* userInputService = [self getUserInputServiceForGameDataModel])
|
||||
{
|
||||
CGPoint tapPoint = [tapTouch locationInView:self];
|
||||
tapTouch = nil;
|
||||
|
||||
shared_ptr<RBX::InputObject> eventDown = RBX::Creatable<RBX::Instance>::create<RBX::InputObject>(RBX::InputObject::TYPE_MOUSEBUTTON1,
|
||||
RBX::InputObject::INPUT_STATE_BEGIN,
|
||||
RBX::Vector3(tapPoint.x,tapPoint.y,0),
|
||||
RBX::Vector3(0,0,0),
|
||||
[self getGame]->getDataModel().get());
|
||||
userInputService->processToolEvent(eventDown);
|
||||
|
||||
shared_ptr<RBX::InputObject> eventUp = RBX::Creatable<RBX::Instance>::create<RBX::InputObject>(RBX::InputObject::TYPE_MOUSEBUTTON1,
|
||||
RBX::InputObject::INPUT_STATE_END,
|
||||
RBX::Vector3(tapPoint.x,tapPoint.y,0),
|
||||
RBX::Vector3(0,0,0),
|
||||
[self getGame]->getDataModel().get());
|
||||
userInputService->processToolEvent(eventUp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// GameKeyboard.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ben Tkacheff on 10/23/12.
|
||||
// Copyright (c) 2012 ROBLOX. All rights reserved.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#import "ControlComponent.h"
|
||||
#include "v8datamodel/Textbox.h"
|
||||
|
||||
@interface GameKeyboard : ControlComponent <UITextFieldDelegate>
|
||||
{
|
||||
UITextField* textView;
|
||||
boost::shared_ptr<RBX::TextBox> currentTextBox;
|
||||
}
|
||||
|
||||
- (id) init;
|
||||
- (void) dealloc;
|
||||
|
||||
+(id) sharedInstance;
|
||||
|
||||
-(void) hideKeyboard;
|
||||
-(bool) showKeyboard:(const char*) stringToShow;
|
||||
-(bool) showKeyboardWithTextBox:(boost::shared_ptr<RBX::TextBox>) newTextBox;
|
||||
-(void)keyboardWillChangeFrame:(NSNotification *) notification;
|
||||
-(void)keyboardWillHide:(NSNotification *) notification;
|
||||
|
||||
-(NSString*) getText;
|
||||
|
||||
-(void) setDefaultString:(NSString*) defaultString;
|
||||
-(void) setParentView:(UIView*) parentView;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,191 @@
|
||||
//
|
||||
// GameKeyboard.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ben Tkacheff on 10/23/12.
|
||||
// Copyright (c) 2012 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "GameKeyboard.h"
|
||||
#import "UIScreen+PortraitBounds.h"
|
||||
#include "v8datamodel/InputObject.h"
|
||||
#import "RobloxInfo.h"
|
||||
|
||||
#define TEXTVIEWHEIGHT 28
|
||||
|
||||
|
||||
static void runExternalReleaseFocus(shared_ptr<RBX::TextBox> currentTextbox) {
|
||||
if (currentTextbox.get())
|
||||
currentTextbox->externalReleaseFocus(currentTextbox->getText().c_str(), false, shared_ptr<RBX::InputObject>());
|
||||
}
|
||||
|
||||
@implementation GameKeyboard
|
||||
|
||||
+ (id)sharedInstance
|
||||
{
|
||||
static dispatch_once_t pred = 0;
|
||||
static GameKeyboard *shared = nil;
|
||||
|
||||
dispatch_once(&pred, ^{ // Need to use GCD for thread-safe allocation
|
||||
shared = [[GameKeyboard alloc] init];
|
||||
});
|
||||
return shared;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
currentTextBox = boost::shared_ptr<RBX::TextBox>();
|
||||
|
||||
CGRect bounds = [[UIScreen mainScreen] portraitBounds];
|
||||
bounds = CGRectMake(0,0,bounds.size.height,bounds.size.width);
|
||||
|
||||
self.frame = bounds;
|
||||
[self setUserInteractionEnabled:NO];
|
||||
|
||||
textView = [[UITextField alloc] initWithFrame:CGRectMake(5,bounds.size.height/2,bounds.size.width - 10,TEXTVIEWHEIGHT)];
|
||||
textView.borderStyle = UITextBorderStyleRoundedRect;
|
||||
textView.delegate = self;
|
||||
textView.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
textView.hidden = YES;
|
||||
|
||||
[self addSubview:textView];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
-(void) hideKeyboard
|
||||
{
|
||||
currentTextBox = boost::shared_ptr<RBX::TextBox>();
|
||||
textView.text = @"";
|
||||
textView.hidden = YES;
|
||||
[self setUserInteractionEnabled:NO];
|
||||
[textView resignFirstResponder];
|
||||
}
|
||||
|
||||
-(void)keyboardWillHide:(NSNotification *) notification
|
||||
{
|
||||
if (RBX::Game* game = [self getGameFromControlView])
|
||||
if (shared_ptr<RBX::DataModel> currDataModel = game->getDataModel())
|
||||
if(currentTextBox && currentTextBox.get())
|
||||
currDataModel->submitTask(boost::bind(runExternalReleaseFocus, currentTextBox), RBX::DataModelJob::TaskType::Write);
|
||||
|
||||
[self hideKeyboard];
|
||||
}
|
||||
|
||||
-(void)keyboardWillChangeFrame:(NSNotification *) notification
|
||||
{
|
||||
if (![RobloxInfo isDeviceOSVersionPreiOS8])
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(),^{
|
||||
//use information pulled from the notification to reposition the keyboard
|
||||
CGRect endFrame = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
||||
CGRect textFrame = CGRectMake(0, endFrame.origin.y - TEXTVIEWHEIGHT, endFrame.size.width, TEXTVIEWHEIGHT);
|
||||
[textView setFrame:textFrame];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
-(void) setDefaultString:(NSString*) defaultString
|
||||
{
|
||||
textView.placeholder = defaultString;
|
||||
}
|
||||
|
||||
-(void) setParentView:(UIView*) parentView
|
||||
{
|
||||
if(!parentView)
|
||||
[self hideKeyboard];
|
||||
|
||||
[parentView addSubview:self];
|
||||
}
|
||||
|
||||
- (bool) showKeyboard:(const char*) stringToShow
|
||||
{
|
||||
if(textView.hidden)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
textView.text = [NSString stringWithUTF8String:stringToShow];
|
||||
|
||||
CGRect bounds = [[UIScreen mainScreen] portraitBounds];
|
||||
bounds = CGRectMake(0,0,bounds.size.height,bounds.size.width);
|
||||
|
||||
int margin = 5;
|
||||
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
|
||||
textView.frame = CGRectMake(margin,bounds.size.height/2.5f,bounds.size.width - (margin + margin),TEXTVIEWHEIGHT);
|
||||
else
|
||||
textView.frame = CGRectMake(margin,bounds.size.height/2,bounds.size.width - (margin + margin),TEXTVIEWHEIGHT);
|
||||
|
||||
textView.hidden = NO;
|
||||
[self setUserInteractionEnabled:YES];
|
||||
[textView becomeFirstResponder];
|
||||
});
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
- (bool) showKeyboardWithTextBox:(boost::shared_ptr<RBX::TextBox>) newTextBox
|
||||
{
|
||||
if(textView.hidden && newTextBox)
|
||||
{
|
||||
currentTextBox = newTextBox;
|
||||
return [self showKeyboard:currentTextBox->getBufferedText().c_str()];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(NSString*) getText
|
||||
{
|
||||
return textView.text;
|
||||
}
|
||||
|
||||
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
|
||||
{
|
||||
if (currentTextBox)
|
||||
{
|
||||
currentTextBox->setBufferedText([textView.text stringByReplacingCharactersInRange:range withString:string].UTF8String, range.location + string.length);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField
|
||||
{
|
||||
if(RBX::UserInputService* userInputService = RBX::ServiceProvider::find<RBX::UserInputService>(currentTextBox.get()))
|
||||
|
||||
if (!userInputService->showStatsBasedOnInputString([textView.text UTF8String]))
|
||||
{
|
||||
userInputService->textboxDidFinishEditing([textView.text UTF8String], true);
|
||||
// make sure our ui calls happen on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||
[self hideKeyboard];
|
||||
});
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) textFieldDidEndEditing:(UITextField *)textField
|
||||
{
|
||||
if(![textView isFirstResponder])
|
||||
return;
|
||||
|
||||
if(RBX::UserInputService* userInputService = RBX::ServiceProvider::find<RBX::UserInputService>(currentTextBox.get()))
|
||||
userInputService->textboxDidFinishEditing([textView.text UTF8String], false);
|
||||
|
||||
// make sure our ui calls happen on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||
[self hideKeyboard];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// GameView.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ben Tkacheff on 11/21/12.
|
||||
// Copyright (c) 2012 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface GameView : UIView
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// GameView.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ben Tkacheff on 11/21/12.
|
||||
// Copyright (c) 2012 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "GameView.h"
|
||||
|
||||
@implementation GameView
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self)
|
||||
{
|
||||
self.userInteractionEnabled = YES;
|
||||
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[super touchesBegan:touches withEvent:event];
|
||||
}
|
||||
|
||||
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[super touchesMoved:touches withEvent:event];
|
||||
}
|
||||
|
||||
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[super touchesEnded:touches withEvent:event];
|
||||
}
|
||||
|
||||
-(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[super touchesCancelled:touches withEvent:event];
|
||||
}
|
||||
|
||||
+ (Class)layerClass
|
||||
{
|
||||
return [CAEAGLLayer class];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// GameViewController.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ben Tkacheff on 11/20/12.
|
||||
// Copyright (c) 2012 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "GameView.h"
|
||||
#include <string>
|
||||
#import "ControlView.h"
|
||||
#import <AdColony/AdColony.h>
|
||||
|
||||
@interface GameViewController : UIViewController <UIWebViewDelegate, AdColonyAdDelegate>
|
||||
{
|
||||
GameView* gameView;
|
||||
UIWebView* externalWebView;
|
||||
UIButton* closeWebviewButton;
|
||||
UIActivityIndicatorView* webViewActivityIndicator;
|
||||
|
||||
CGFloat webviewTweenTime;
|
||||
}
|
||||
|
||||
-(void) playVideoAd;
|
||||
|
||||
-(void) resizeGameView;
|
||||
-(void) openUrlWindow:(std::string) url;
|
||||
-(void) closeUrlWindow;
|
||||
-(void) closeUrlWindow:(id) sender;
|
||||
|
||||
- (void) addControlView:(ControlView*)controlView;
|
||||
-(ControlView*) getControlView;
|
||||
|
||||
- (void) onAdColonyAdStartedInZone:(NSString *)zoneID;
|
||||
- (void) onAdColonyAdAttemptFinished:(BOOL)shown inZone:(NSString *)zoneID;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,308 @@
|
||||
//
|
||||
// GameViewController.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ben Tkacheff on 11/20/12.
|
||||
// Copyright (c) 2012 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "GameViewController.h"
|
||||
#import "LoginManager.h"
|
||||
#import "RobloxInfo.h"
|
||||
#import "StoreManager.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "UIScreen+PortraitBounds.h"
|
||||
#import "PlaceLauncher.h"
|
||||
#import "RobloxNotifications.h"
|
||||
|
||||
#include "v8datamodel/LoginService.h"
|
||||
#include "v8datamodel/GuiService.h"
|
||||
#include "v8datamodel/AdService.h"
|
||||
#include "util/SoundService.h"
|
||||
|
||||
DYNAMIC_FASTSTRINGVARIABLE(AdColonyAppId, "app02d1db3451cc4b6b97");
|
||||
DYNAMIC_FASTSTRINGVARIABLE(AdColonyZoneId, "vz073fd9a8cf0c447cbc");
|
||||
|
||||
@implementation GameViewController
|
||||
{
|
||||
ControlView* _controlView;
|
||||
}
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if (self)
|
||||
{
|
||||
webviewTweenTime = 0.3;
|
||||
|
||||
CGSize screenSize = [[UIScreen mainScreen] portraitBounds].size;
|
||||
gameView = [[GameView alloc] initWithFrame:CGRectMake(0, 0, screenSize.height, screenSize.width)];
|
||||
self.view = gameView;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(handleGoingBackgroundNotification:)
|
||||
name:RBX_NOTIFY_GAME_START_LEAVING
|
||||
object:nil ];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) dealloc
|
||||
{
|
||||
if(externalWebView)
|
||||
{
|
||||
[externalWebView removeFromSuperview];
|
||||
externalWebView = nil;
|
||||
}
|
||||
|
||||
_controlView = nil;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
gameView = nil;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
NSDictionary* dictionary = [NSDictionary dictionaryWithObjectsAndKeys: [RobloxInfo getUserAgentString], @"UserAgent", nil];
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
|
||||
}
|
||||
|
||||
-(void) resizeGameView
|
||||
{
|
||||
[gameView layoutSubviews];
|
||||
}
|
||||
|
||||
- (BOOL)prefersStatusBarHidden
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)shouldAutorotate
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
#ifdef __IPHONE_9_0
|
||||
-(UIInterfaceOrientationMask) supportedInterfaceOrientations
|
||||
#else
|
||||
-(NSUInteger)supportedInterfaceOrientations
|
||||
#endif
|
||||
{
|
||||
return UIInterfaceOrientationMaskLandscape;
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
|
||||
{
|
||||
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
||||
return (orientation == UIInterfaceOrientationLandscapeRight) ? UIInterfaceOrientationLandscapeRight : UIInterfaceOrientationLandscapeLeft;
|
||||
}
|
||||
|
||||
- (void) addControlView:(ControlView*)controlView
|
||||
{
|
||||
_controlView = controlView;
|
||||
|
||||
[self.view addSubview:controlView];
|
||||
}
|
||||
|
||||
-(ControlView*) getControlView
|
||||
{
|
||||
return _controlView;
|
||||
}
|
||||
|
||||
-(void) playVideoAd
|
||||
{
|
||||
NSString* adColonyZoneId = [NSString stringWithUTF8String:DFString::AdColonyZoneId.c_str()];
|
||||
|
||||
if(ControlView* controlView = [self getControlView])
|
||||
{
|
||||
if(shared_ptr<RBX::Game> game = [controlView getGame])
|
||||
{
|
||||
if(RBX::DataModel* dm = game->getDataModel().get())
|
||||
{
|
||||
if(RBX::Soundscape::SoundService* soundService = RBX::ServiceProvider::find<RBX::Soundscape::SoundService>(dm))
|
||||
{
|
||||
soundService->muteAllChannels(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AdColony playVideoAdForZone:adColonyZoneId withDelegate:self];
|
||||
}
|
||||
|
||||
- (void) onAdColonyAdStartedInZone:(NSString *)zoneID
|
||||
{
|
||||
if (ControlView* controlView = [self getControlView])
|
||||
{
|
||||
[controlView setUserInteractionEnabled:false];
|
||||
if (RbxInputView* inputView = [controlView getRbxInputView])
|
||||
{
|
||||
[inputView setUserInteractionEnabled:false];
|
||||
[inputView cancelAllTouches];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) onAdColonyAdAttemptFinished:(BOOL)shown inZone:(NSString *)zoneID
|
||||
{
|
||||
if(ControlView* controlView = [self getControlView])
|
||||
{
|
||||
[controlView setUserInteractionEnabled:true];
|
||||
if (RbxInputView* inputView = [controlView getRbxInputView])
|
||||
{
|
||||
[inputView setUserInteractionEnabled:true];
|
||||
}
|
||||
|
||||
if(shared_ptr<RBX::Game> game = [controlView getGame])
|
||||
{
|
||||
if(RBX::DataModel* dm = game->getDataModel().get())
|
||||
{
|
||||
if(RBX::Soundscape::SoundService* soundService = RBX::ServiceProvider::find<RBX::Soundscape::SoundService>(dm))
|
||||
{
|
||||
soundService->muteAllChannels(false);
|
||||
}
|
||||
if(RBX::AdService* adService = RBX::ServiceProvider::find<RBX::AdService>(dm))
|
||||
{
|
||||
adService->videoAdClosed(shown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shown)
|
||||
{
|
||||
//todo: do some webcall here for revenue sharing/stat tracking
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
|
||||
{
|
||||
id storeManager = GetStoreMgr;
|
||||
|
||||
if ([storeManager isKindOfClass:[StoreManager class]])
|
||||
{
|
||||
if([storeManager checkForInAppPurchases:request navigationType:navigationType])
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)webViewDidFinishLoad:(UIWebView *)webView
|
||||
{
|
||||
if (webView == externalWebView && webViewActivityIndicator)
|
||||
{
|
||||
[webViewActivityIndicator setHidden:YES];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) signalGuiServiceUrlWindowClosedOnDataModel:(RBX::DataModel*) dataModel
|
||||
{
|
||||
if(dataModel)
|
||||
if(RBX::GuiService* guiService = RBX::ServiceProvider::find<RBX::GuiService>(dataModel))
|
||||
guiService->urlWindowClosed();
|
||||
}
|
||||
|
||||
-(void) closeUrlWindow:(id) sender
|
||||
{
|
||||
if(externalWebView)
|
||||
{
|
||||
UIWebView* tempWebView = externalWebView;
|
||||
externalWebView = nil;
|
||||
|
||||
if(ControlView* controlView = [self getControlView])
|
||||
if(shared_ptr<RBX::Game> game = [controlView getGame])
|
||||
{
|
||||
[self signalGuiServiceUrlWindowClosedOnDataModel:game->getDataModel().get()];
|
||||
}
|
||||
|
||||
CGSize screenSize = [[UIScreen mainScreen] portraitBounds].size;
|
||||
screenSize = CGSizeMake(screenSize.height, screenSize.width);
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[UIView animateWithDuration:webviewTweenTime
|
||||
delay:0
|
||||
options:UIViewAnimationOptionTransitionNone
|
||||
animations:^{
|
||||
tempWebView.frame = CGRectMake(screenSize.width/2 - tempWebView.frame.size.width/2, screenSize.height, tempWebView.frame.size.width, tempWebView.frame.size.height);
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[tempWebView removeFromSuperview];
|
||||
}
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
-(void) closeUrlWindow
|
||||
{
|
||||
[self closeUrlWindow:nil];
|
||||
}
|
||||
|
||||
-(void) openUrlWindow:(std::string) url
|
||||
{
|
||||
if(externalWebView)
|
||||
return;
|
||||
|
||||
CGSize screenSize = [[UIScreen mainScreen] portraitBounds].size;
|
||||
// switch so dimensions are in landscape
|
||||
screenSize = CGSizeMake(screenSize.height, screenSize.width);
|
||||
|
||||
int webviewWidth = 660;
|
||||
int webviewHeight = 400;
|
||||
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
|
||||
{
|
||||
webviewWidth = screenSize.width;
|
||||
webviewHeight = screenSize.height;
|
||||
}
|
||||
|
||||
if (externalWebView == nil)
|
||||
{
|
||||
int closeButtonSize = 22;
|
||||
int closeButtonOffset = 5;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
externalWebView = [[UIWebView alloc] initWithFrame:CGRectMake(screenSize.width/2 - webviewWidth/2, screenSize.height, webviewWidth, webviewHeight)];
|
||||
externalWebView.delegate = self;
|
||||
externalWebView.userInteractionEnabled = YES;
|
||||
externalWebView.scalesPageToFit = NO;
|
||||
|
||||
webViewActivityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
[webViewActivityIndicator setHidden:NO];
|
||||
[webViewActivityIndicator startAnimating];
|
||||
[webViewActivityIndicator setFrame:CGRectMake(externalWebView.frame.size.width/2 - webViewActivityIndicator.frame.size.width/2,
|
||||
externalWebView.frame.size.height/2 - webViewActivityIndicator.frame.size.height/2,
|
||||
webViewActivityIndicator.frame.size.width,
|
||||
webViewActivityIndicator.frame.size.height)];
|
||||
|
||||
closeWebviewButton = [[UIButton alloc] initWithFrame:CGRectMake(externalWebView.frame.size.width - closeButtonSize - closeButtonOffset, closeButtonOffset, closeButtonSize, closeButtonSize)];
|
||||
[closeWebviewButton setImage:[UIImage imageNamed:@"Clear.png"] forState:UIControlStateNormal];
|
||||
[closeWebviewButton addTarget:self action:@selector(closeUrlWindow:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[externalWebView addSubview:closeWebviewButton];
|
||||
[externalWebView addSubview:webViewActivityIndicator];
|
||||
|
||||
if(ControlView* controlView = [self getControlView])
|
||||
[controlView addSubview:externalWebView];
|
||||
});
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[externalWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithUTF8String:url.c_str()]]]];
|
||||
[UIView animateWithDuration:webviewTweenTime animations:^{
|
||||
externalWebView.frame = CGRectMake(screenSize.width/2 - webviewWidth/2, screenSize.height/2 - webviewHeight/2, externalWebView.frame.size.width, externalWebView.frame.size.height);
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
-(void) handleGoingBackgroundNotification:(NSNotification*) leaveGameNotification
|
||||
{
|
||||
if ([AdColony videoAdCurrentlyRunning])
|
||||
[AdColony cancelAd];
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// RbxInputView.h
|
||||
// Roblox iOS Shared Code
|
||||
//
|
||||
// Created by Ben Tkacheff on 10/25/13.
|
||||
// Copyright (c) 2013 ROBLOX. All rights reserved.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#import <GameController/GameController.h>
|
||||
#import <CoreMotion/CoreMotion.h>
|
||||
#import "ControlComponent.h"
|
||||
|
||||
#include "v8datamodel/TouchInputService.h"
|
||||
#include "v8datamodel/UserInputService.h"
|
||||
|
||||
@class RbxInputView;
|
||||
|
||||
typedef std::vector<G3D::Vector3> KeycodeInputs;
|
||||
typedef boost::unordered_map<RBX::KeyCode, KeycodeInputs> BufferedGamepadState;
|
||||
typedef boost::unordered_map<RBX::InputObject::UserInputType, BufferedGamepadState> BufferedGamepadStates;
|
||||
|
||||
static boost::mutex ControllerBufferMutex;
|
||||
|
||||
@interface RbxInputView : ControlComponent <UIGestureRecognizerDelegate>
|
||||
{
|
||||
G3D::Vector2int16 windowSize;
|
||||
|
||||
// Gesture Input
|
||||
// each direction needs its own recognizer, nice...
|
||||
UISwipeGestureRecognizer *swipeRightRecognizer;
|
||||
UISwipeGestureRecognizer *swipeLeftRecognizer;
|
||||
UISwipeGestureRecognizer *swipeUpRecognizer;
|
||||
UISwipeGestureRecognizer *swipeDownRecognizer;
|
||||
|
||||
UITapGestureRecognizer *tapRecognizer;
|
||||
UITapGestureRecognizer *twoFingerTapRecognizer;
|
||||
UITapGestureRecognizer *threeFingerTapRecognizer;
|
||||
|
||||
UIRotationGestureRecognizer* rotationRecognizer;
|
||||
UILongPressGestureRecognizer* longPressRecognizer;
|
||||
UIPinchGestureRecognizer *pinchRecognizer;
|
||||
UIPanGestureRecognizer *panRecognizer;
|
||||
|
||||
|
||||
// Touch Input
|
||||
boost::unordered_map<void*, shared_ptr<RBX::InputObject> > touchInputMap;
|
||||
NSMutableArray* storedTouches;
|
||||
|
||||
|
||||
// Motion Input
|
||||
CMMotionManager *motionManager;
|
||||
NSOperationQueue *motionQueue;
|
||||
CMAttitude* refAttitude;
|
||||
|
||||
|
||||
// Controller Input
|
||||
bool paused;
|
||||
std::map<int, bool> controllersConnectedMap;
|
||||
BufferedGamepadStates controllerBufferMap;
|
||||
|
||||
// DataModel service references
|
||||
weak_ptr<RBX::TouchInputService> weakTouchInputService;
|
||||
}
|
||||
|
||||
- (id) init: (CGRect)frame;
|
||||
// any init that requires use of a datamodel or its services, put in this function
|
||||
- (void) datamodelInit;
|
||||
|
||||
// Basic Input handling
|
||||
-(void) sendTouchEvent:(UITouch*) touch;
|
||||
-(void) sendTouchEvent:(UITouch*) touch shouldOverride:(BOOL) shouldOverride overrideState:(UITouchPhase) overrideState;
|
||||
|
||||
-(void) cancelAllTouches;
|
||||
|
||||
-(void) basicGestureConfig:(UIGestureRecognizer*) gesture;
|
||||
|
||||
// Gesture handlers
|
||||
-(void) twoFingerPinch:(UIPinchGestureRecognizer *)recognizer;
|
||||
-(void) tapGesture:(UITapGestureRecognizer*) recognizer;
|
||||
-(void) swipeGesture:(UISwipeGestureRecognizer*)recognizer;
|
||||
-(void) longPressGesture:(UILongPressGestureRecognizer*) recognizer;
|
||||
-(void) panGesture:(UIPanGestureRecognizer*) recognizer;
|
||||
-(RBX::UserInputService::SwipeDirection) getRbxSwipeDirection:(UISwipeGestureRecognizerDirection) uiSwipeDirection;
|
||||
|
||||
// Motion Stuff
|
||||
-(void) startMotionUpdates;
|
||||
+(BOOL) isGyroscopeAvailable;
|
||||
|
||||
// Controller Stuff
|
||||
-(void) gcControllerConnected:(NSNotification*) notification;
|
||||
-(void) gcControllerDisconnected:(NSNotification*) notification;
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user