2014-03-10 19:33:57 +08:00
/****************************************************************************
Copyright ( c ) 2013 cocos2d - x . org
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "Runtime.h"
# include "lua_debugger.h"
# include "CCLuaEngine.h"
# include "cocos2d.h"
# ifdef _WIN32
# include <direct.h>
# else
# include <sys/stat.h>
# endif
# include <vector>
# include <string>
using namespace std ;
using namespace cocos2d ;
2014-03-18 18:24:58 +08:00
std : : string g_resourcePath ;
2014-03-10 19:33:57 +08:00
extern string getIPAddress ( ) ;
2014-03-11 16:52:06 +08:00
string getRuntimeVersion ( )
{
return " 0.0.1 " ;
}
2014-03-10 19:33:57 +08:00
void startScript ( string strDebugArg )
{
// register lua engine
auto engine = LuaEngine : : getInstance ( ) ;
if ( ! strDebugArg . empty ( ) )
{
engine - > executeString ( strDebugArg . c_str ( ) ) ;
}
cocos2d : : log ( " debug args = %s " , strDebugArg . c_str ( ) ) ;
engine - > executeScriptFile ( " src/main.lua " ) ;
}
2014-03-11 16:52:06 +08:00
void reloadScript ( const string & modulefile )
2014-03-10 19:33:57 +08:00
{
2014-03-11 16:52:06 +08:00
string strfile = modulefile ;
if ( strfile . empty ( ) )
{
strfile = " src/main.lua " ;
}
LuaEngine : : getInstance ( ) - > reload ( strfile . c_str ( ) ) ;
2014-03-10 19:33:57 +08:00
}
class VisibleRect
{
public :
static Rect getVisibleRect ( ) ;
static Point left ( ) ;
static Point right ( ) ;
static Point top ( ) ;
static Point bottom ( ) ;
static Point center ( ) ;
static Point leftTop ( ) ;
static Point rightTop ( ) ;
static Point leftBottom ( ) ;
static Point rightBottom ( ) ;
private :
static void lazyInit ( ) ;
static Rect s_visibleRect ;
} ;
Rect VisibleRect : : s_visibleRect ;
void VisibleRect : : lazyInit ( )
{
// no lazy init
// Useful if we change the resolution in runtime
s_visibleRect = Director : : getInstance ( ) - > getOpenGLView ( ) - > getVisibleRect ( ) ;
}
Rect VisibleRect : : getVisibleRect ( )
{
lazyInit ( ) ;
return s_visibleRect ;
}
Point VisibleRect : : left ( )
{
lazyInit ( ) ;
return Point ( s_visibleRect . origin . x , s_visibleRect . origin . y + s_visibleRect . size . height / 2 ) ;
}
Point VisibleRect : : right ( )
{
lazyInit ( ) ;
return Point ( s_visibleRect . origin . x + s_visibleRect . size . width , s_visibleRect . origin . y + s_visibleRect . size . height / 2 ) ;
}
Point VisibleRect : : top ( )
{
lazyInit ( ) ;
return Point ( s_visibleRect . origin . x + s_visibleRect . size . width / 2 , s_visibleRect . origin . y + s_visibleRect . size . height ) ;
}
Point VisibleRect : : bottom ( )
{
lazyInit ( ) ;
return Point ( s_visibleRect . origin . x + s_visibleRect . size . width / 2 , s_visibleRect . origin . y ) ;
}
Point VisibleRect : : center ( )
{
lazyInit ( ) ;
return Point ( s_visibleRect . origin . x + s_visibleRect . size . width / 2 , s_visibleRect . origin . y + s_visibleRect . size . height / 2 ) ;
}
Point VisibleRect : : leftTop ( )
{
lazyInit ( ) ;
return Point ( s_visibleRect . origin . x , s_visibleRect . origin . y + s_visibleRect . size . height ) ;
}
Point VisibleRect : : rightTop ( )
{
lazyInit ( ) ;
return Point ( s_visibleRect . origin . x + s_visibleRect . size . width , s_visibleRect . origin . y + s_visibleRect . size . height ) ;
}
Point VisibleRect : : leftBottom ( )
{
lazyInit ( ) ;
return s_visibleRect . origin ;
}
Point VisibleRect : : rightBottom ( )
{
lazyInit ( ) ;
return Point ( s_visibleRect . origin . x + s_visibleRect . size . width , s_visibleRect . origin . y ) ;
}
class ConnectWaitLayer : public Layer
{
public :
ConnectWaitLayer ( )
{
string strip = getIPAddress ( ) ;
char szIPAddress [ 512 ] = { 0 } ;
sprintf ( szIPAddress , " LocalIP: %s " , strip . c_str ( ) ) ;
auto label = LabelTTF : : create ( szIPAddress , " Arial " , 24 ) ;
addChild ( label , 9999 ) ;
label - > setPosition ( Point ( VisibleRect : : center ( ) . x , VisibleRect : : top ( ) . y - 30 ) ) ;
2014-03-21 11:56:21 +08:00
string strShowMsg = " " ;
if ( CC_PLATFORM_WIN32 = = CC_TARGET_PLATFORM | | CC_PLATFORM_MAC = = CC_TARGET_PLATFORM )
{
strShowMsg = " waiting for debugger to connect ... " ;
} else
{
strShowMsg = " waiting for file transfer ... " ;
}
auto labelwait = LabelTTF : : create ( strShowMsg . c_str ( ) , " Arial " , 22 ) ;
2014-03-10 19:33:57 +08:00
addChild ( labelwait , 10000 ) ;
labelwait - > setPosition ( Point ( VisibleRect : : center ( ) . x , VisibleRect : : center ( ) . y ) ) ;
auto labelPlay = LabelTTF : : create ( " play " , " Arial " , 20 ) ;
auto menuItem = MenuItemLabel : : create ( labelPlay , CC_CALLBACK_1 ( ConnectWaitLayer : : playerCallback , this ) ) ;
auto menu = Menu : : create ( menuItem , NULL ) ;
menu - > setPosition ( Point : : ZERO ) ;
menuItem - > setPosition ( Point ( VisibleRect : : right ( ) . x - 50 , VisibleRect : : bottom ( ) . y + 25 ) ) ;
addChild ( menu , 1 ) ;
//_scheduler = CCDirector::sharedDirector()->getScheduler();
//scheduleUpdate();
}
void playerCallback ( Object * sender )
{
startScript ( " " ) ;
}
} ;
# if defined(_MSC_VER) || defined(__MINGW32__)
# include <io.h>
# include <WS2tcpip.h>
# define bzero(a, b) memset(a, 0, b);
# else
# include <netdb.h>
# include <unistd.h>
# include <arpa/inet.h>
# include <netinet/in.h>
# include <sys/socket.h>
# include <sys/un.h>
# endif
class FileServer
{
public :
FileServer ( )
{
_listenfd = - 1 ;
_running = false ;
_endThread = false ;
}
bool listenOnTCP ( int port ) ;
void stop ( ) ;
private :
bool recv_file ( int fd ) ;
void addClient ( ) ;
void loop ( ) ;
// file descriptor: socket, console, etc.
int _listenfd ;
int _maxfd ;
std : : vector < int > _fds ;
std : : thread _thread ;
fd_set _read_set ;
bool _running ;
bool _endThread ;
} ;
bool FileServer : : listenOnTCP ( int port )
{
int listenfd , n ;
const int on = 1 ;
struct addrinfo hints , * res , * ressave ;
char serv [ 30 ] ;
snprintf ( serv , sizeof ( serv ) - 1 , " %d " , port ) ;
serv [ sizeof ( serv ) - 1 ] = 0 ;
bzero ( & hints , sizeof ( struct addrinfo ) ) ;
hints . ai_flags = AI_PASSIVE ;
hints . ai_family = AF_INET ; // AF_UNSPEC: Do we need IPv6 ?
hints . ai_socktype = SOCK_STREAM ;
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
WSADATA wsaData ;
n = WSAStartup ( MAKEWORD ( 2 , 2 ) , & wsaData ) ;
# endif
if ( ( n = getaddrinfo ( NULL , serv , & hints , & res ) ) ! = 0 ) {
fprintf ( stderr , " net_listen error for %s: %s " , serv , gai_strerror ( n ) ) ;
return false ;
}
ressave = res ;
do {
listenfd = socket ( res - > ai_family , res - > ai_socktype , res - > ai_protocol ) ;
if ( listenfd < 0 )
continue ; /* error, try next one */
setsockopt ( listenfd , SOL_SOCKET , SO_REUSEADDR , ( const char * ) & on , sizeof ( on ) ) ;
if ( : : bind ( listenfd , res - > ai_addr , res - > ai_addrlen ) = = 0 )
break ; /* success */
close ( listenfd ) ; /* bind error, close and try next one */
} while ( ( res = res - > ai_next ) ! = NULL ) ;
if ( res = = NULL ) {
perror ( " net_listen: " ) ;
freeaddrinfo ( ressave ) ;
return false ;
}
listen ( listenfd , 1 ) ;
if ( res - > ai_family = = AF_INET )
{
char buf [ INET_ADDRSTRLEN ] = " " ;
struct sockaddr_in * sin = ( struct sockaddr_in * ) res - > ai_addr ;
if ( inet_ntop ( res - > ai_family , & sin - > sin_addr , buf , sizeof ( buf ) ) ! = NULL )
cocos2d : : log ( " Console: listening on %s : %d " , buf , ntohs ( sin - > sin_port ) ) ;
else
perror ( " inet_ntop " ) ;
} else if ( res - > ai_family = = AF_INET6 )
{
char buf [ INET6_ADDRSTRLEN ] = " " ;
struct sockaddr_in6 * sin = ( struct sockaddr_in6 * ) res - > ai_addr ;
if ( inet_ntop ( res - > ai_family , & sin - > sin6_addr , buf , sizeof ( buf ) ) ! = NULL )
cocos2d : : log ( " Console: listening on %s : %d " , buf , ntohs ( sin - > sin6_port ) ) ;
else
perror ( " inet_ntop " ) ;
}
freeaddrinfo ( ressave ) ;
_listenfd = listenfd ;
_thread = std : : thread ( std : : bind ( & FileServer : : loop , this ) ) ;
return true ;
}
void FileServer : : stop ( )
{
if ( _running ) {
_endThread = true ;
_thread . join ( ) ;
}
}
2014-03-18 18:24:58 +08:00
string & replaceAll ( string & str , const string & old_value , const string & new_value )
2014-03-10 19:33:57 +08:00
{
while ( true )
{
int pos = 0 ;
if ( ( pos = str . find ( old_value , 0 ) ) ! = string : : npos )
str . replace ( pos , old_value . length ( ) , new_value ) ;
else break ;
}
return str ;
}
bool CreateDir ( const char * sPathName )
{
char DirName [ 256 ] = { 0 } ;
strcpy ( DirName , sPathName ) ;
int i , len = strlen ( DirName ) ;
if ( DirName [ len - 1 ] ! = ' / ' )
strcat ( DirName , " / " ) ;
len = strlen ( DirName ) ;
for ( i = 1 ; i < len ; i + + )
{
if ( DirName [ i ] = = ' / ' )
{
DirName [ i ] = 0 ;
if ( access ( DirName , NULL ) ! = 0 )
{
# ifdef _WIN32
if ( mkdir ( DirName /*, 0755*/ ) = = - 1 )
# else
if ( mkdir ( DirName , 0755 ) = = - 1 )
# endif
{
perror ( " mkdir error " ) ;
return false ;
}
}
DirName [ i ] = ' / ' ;
}
}
return true ;
}
bool FileServer : : recv_file ( int fd )
{
char buffer [ 1024 ] = { 0 } ;
2014-03-15 18:30:58 +08:00
char namelen [ 5 ] = { 0 } ;
2014-03-10 19:33:57 +08:00
if ( recv ( fd , namelen , 4 , 0 ) < = 0 ) {
return false ;
}
if ( recv ( fd , buffer , atoi ( namelen ) , 0 ) < = 0 ) {
return false ;
}
char fullfilename [ 1024 ] = { 0 } ;
2014-03-18 18:24:58 +08:00
sprintf ( fullfilename , " %s%s " , g_resourcePath . c_str ( ) , buffer ) ;
2014-03-10 19:33:57 +08:00
string file ( fullfilename ) ;
sprintf ( fullfilename , " %s " , file . c_str ( ) ) ;
cocos2d : : log ( " recv fullfilename = %s " , fullfilename ) ;
CreateDir ( file . substr ( 0 , file . find_last_of ( " / " ) ) . c_str ( ) ) ;
FILE * fp = fopen ( fullfilename , " wb " ) ;
int length = 0 ;
while ( ( length = recv ( fd , fullfilename , sizeof ( fullfilename ) , 0 ) ) > 0 ) {
fwrite ( fullfilename , sizeof ( char ) , length , fp ) ;
}
fclose ( fp ) ;
2014-03-16 17:32:08 +08:00
string finish ( " finish \n " ) ;
send ( fd , finish . c_str ( ) , finish . size ( ) , 0 ) ;
2014-03-10 19:33:57 +08:00
return true ;
}
void FileServer : : addClient ( )
{
struct sockaddr client ;
socklen_t client_len ;
/* new client */
client_len = sizeof ( client ) ;
int fd = accept ( _listenfd , ( struct sockaddr * ) & client , & client_len ) ;
// add fd to list of FD
if ( fd ! = - 1 ) {
FD_SET ( fd , & _read_set ) ;
_fds . push_back ( fd ) ;
_maxfd = std : : max ( _maxfd , fd ) ;
}
}
void FileServer : : loop ( )
{
fd_set copy_set ;
struct timeval timeout , timeout_copy ;
_running = true ;
FD_ZERO ( & _read_set ) ;
FD_SET ( _listenfd , & _read_set ) ;
_maxfd = _listenfd ;
timeout . tv_sec = 0 ;
/* 0.016 seconds. Wake up once per frame at 60PFS */
timeout . tv_usec = 16000 ;
while ( ! _endThread ) {
copy_set = _read_set ;
timeout_copy = timeout ;
int nready = select ( _maxfd + 1 , & copy_set , NULL , NULL , & timeout_copy ) ;
if ( nready = = - 1 )
{
/* error */
if ( errno ! = EINTR )
log ( " Abnormal error in select() \n " ) ;
continue ;
}
else if ( nready = = 0 )
{
/* timeout. do somethig ? */
}
else
{
/* new client */
if ( FD_ISSET ( _listenfd , & copy_set ) ) {
addClient ( ) ;
if ( - - nready < = 0 )
continue ;
}
/* data from client */
std : : vector < int > to_remove ;
for ( const auto & fd : _fds ) {
if ( FD_ISSET ( fd , & copy_set ) ) {
if ( ! recv_file ( fd ) ) {
to_remove . push_back ( fd ) ;
}
if ( - - nready < = 0 )
break ;
}
}
/* remove closed conections */
for ( int fd : to_remove ) {
FD_CLR ( fd , & _read_set ) ;
_fds . erase ( std : : remove ( _fds . begin ( ) , _fds . end ( ) , fd ) , _fds . end ( ) ) ;
}
}
}
// clean up: ignore stdin, stdout and stderr
for ( const auto & fd : _fds )
2014-03-11 16:52:06 +08:00
{
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
closesocket ( fd ) ;
# else
2014-03-10 19:33:57 +08:00
close ( fd ) ;
2014-03-11 16:52:06 +08:00
# endif
}
2014-03-10 19:33:57 +08:00
2014-03-11 16:52:06 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
closesocket ( _listenfd ) ;
WSACleanup ( ) ;
# else
close ( _listenfd ) ;
# endif
2014-03-10 19:33:57 +08:00
_running = false ;
}
class ConsoleCustomCommand
{
public :
ConsoleCustomCommand ( ) : _fileserver ( nullptr )
{
cocos2d : : Console * _console = Director : : getInstance ( ) - > getConsole ( ) ;
static struct Console : : Command commands [ ] = {
{ " shutdownapp " , " exit runtime app " , std : : bind ( & ConsoleCustomCommand : : onShutDownApp , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) } ,
{ " start-logic " , " run game logic script.Arg:[debugArg] " , std : : bind ( & ConsoleCustomCommand : : onRunLogicScript , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) } ,
{ " reload " , " reload script.Args:[filepath] " , std : : bind ( & ConsoleCustomCommand : : onReloadScriptFile , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) } ,
2014-03-11 16:52:06 +08:00
{ " getversion " , " get runtime version. " , std : : bind ( & ConsoleCustomCommand : : onRuntimeVersion , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) } ,
2014-03-10 19:33:57 +08:00
} ;
for ( int i = 0 ; i < sizeof ( commands ) / sizeof ( Console : : Command ) ; i + + ) {
_console - > addCommand ( commands [ i ] ) ;
}
2014-03-12 11:04:56 +08:00
_console - > listenOnTCP ( 6010 ) ;
2014-03-10 19:33:57 +08:00
_fileserver = new FileServer ( ) ;
2014-03-12 11:04:56 +08:00
_fileserver - > listenOnTCP ( 6020 ) ;
2014-03-10 19:33:57 +08:00
}
~ ConsoleCustomCommand ( )
{
2014-03-18 18:24:58 +08:00
Director : : getInstance ( ) - > getConsole ( ) - > stop ( ) ;
2014-03-10 19:33:57 +08:00
_fileserver - > stop ( ) ;
if ( _fileserver ) {
delete _fileserver ;
_fileserver = nullptr ;
}
}
void onRunLogicScript ( int fd , const std : : string & args )
{
Director : : getInstance ( ) - > getScheduler ( ) - > performFunctionInCocosThread ( [ = ] ( ) {
char szDebugArg [ 1024 ] = { 0 } ;
sprintf ( szDebugArg , " require('debugger')(%s,'%s') " , args . c_str ( ) , _writepath . c_str ( ) ) ;
startScript ( szDebugArg ) ;
} ) ;
}
void onReloadScriptFile ( int fd , const std : : string & args )
{
2014-03-11 16:52:06 +08:00
Director : : getInstance ( ) - > getScheduler ( ) - > performFunctionInCocosThread ( [ = ] ( ) {
reloadScript ( args . c_str ( ) ) ;
2014-03-10 19:33:57 +08:00
} ) ;
}
2014-03-11 16:52:06 +08:00
void onRuntimeVersion ( int fd , const std : : string & args )
{
string runtimeVer = getRuntimeVersion ( ) ;
2014-03-16 17:32:08 +08:00
runtimeVer + = " \n " ;
2014-03-11 16:52:06 +08:00
send ( fd , runtimeVer . c_str ( ) , runtimeVer . size ( ) , 0 ) ;
}
2014-03-10 19:33:57 +08:00
void onShutDownApp ( int fd , const std : : string & args )
{
Director : : getInstance ( ) - > getScheduler ( ) - > performFunctionInCocosThread ( [ ] ( ) {
2014-03-17 20:46:49 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
extern void shutDownApp ( ) ;
shutDownApp ( ) ;
# else
exit ( 0 ) ;
# endif
2014-03-10 19:33:57 +08:00
} ) ;
}
private :
FileServer * _fileserver ;
string _writepath ;
} ;
void startRuntime ( )
{
2014-03-19 17:23:06 +08:00
vector < string > searchPathArray ;
searchPathArray = FileUtils : : getInstance ( ) - > getSearchPaths ( ) ;
2014-03-18 18:24:58 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
if ( g_resourcePath . empty ( ) )
{
2014-03-19 17:23:06 +08:00
extern std : : string getCurAppPath ( ) ;
string resourcePath = getCurAppPath ( ) ;
resourcePath . append ( " /../../ " ) ;
resourcePath = replaceAll ( resourcePath , " \\ " , " / " ) ;
g_resourcePath = resourcePath ;
2014-03-18 18:24:58 +08:00
}
# else
g_resourcePath = FileUtils : : getInstance ( ) - > getWritablePath ( ) ;
# endif
2014-03-19 17:23:06 +08:00
2014-03-18 18:24:58 +08:00
g_resourcePath = replaceAll ( g_resourcePath , " \\ " , " / " ) ;
2014-03-19 17:23:06 +08:00
searchPathArray . insert ( searchPathArray . begin ( ) , g_resourcePath ) ;
FileUtils : : getInstance ( ) - > setSearchPaths ( searchPathArray ) ;
2014-03-18 18:24:58 +08:00
static ConsoleCustomCommand s_customCommand ;
2014-03-10 19:33:57 +08:00
auto engine = LuaEngine : : getInstance ( ) ;
ScriptEngineManager : : getInstance ( ) - > setScriptEngine ( engine ) ;
luaopen_debugger ( engine - > getLuaStack ( ) - > getLuaState ( ) ) ;
2014-03-18 18:24:58 +08:00
2014-03-10 19:33:57 +08:00
auto scene = Scene : : create ( ) ;
auto layer = new ConnectWaitLayer ( ) ;
layer - > autorelease ( ) ;
auto director = Director : : getInstance ( ) ;
scene - > addChild ( layer ) ;
director - > runWithScene ( scene ) ;
}
// SimulatorConfig
SimulatorConfig * SimulatorConfig : : s_sharedInstance = NULL ;
SimulatorConfig * SimulatorConfig : : getInstance ( void )
{
if ( ! s_sharedInstance )
{
s_sharedInstance = new SimulatorConfig ( ) ;
}
return s_sharedInstance ;
}
SimulatorConfig : : SimulatorConfig ( void )
{
m_screenSizeArray . push_back ( SimulatorScreenSize ( " iPhone 3Gs (480x320) " , 480 , 320 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " iPhone 4 (960x640) " , 960 , 640 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " iPhone 5 (1136x640) " , 1136 , 640 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " iPad (1024x768) " , 1024 , 768 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " iPad Retina (2048x1536) " , 2048 , 1536 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " Android (800x480) " , 800 , 480 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " Android (854x480) " , 854 , 480 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " Android (960x540) " , 960 , 540 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " Android (1024x600) " , 1024 , 600 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " Android (1280x720) " , 1280 , 720 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " Android (1280x800) " , 1280 , 800 ) ) ;
m_screenSizeArray . push_back ( SimulatorScreenSize ( " Android (1920x1080) " , 1920 , 1080 ) ) ;
}
int SimulatorConfig : : getScreenSizeCount ( void )
{
return ( int ) m_screenSizeArray . size ( ) ;
}
const SimulatorScreenSize SimulatorConfig : : getScreenSize ( int index )
{
return m_screenSizeArray . at ( index ) ;
}