mirror of https://github.com/axmolengine/axmol.git
Merge commit 'refs/pull/4433/head' of git://github.com/cocos2d/cocos2d-x into ccconsole
Conflicts: cocos/scripting/auto-generated
This commit is contained in:
commit
b0af2667f8
|
@ -1 +1 @@
|
|||
e7cd3941f350f6acc4b4e1c5923af10694060848
|
||||
c3b97117ff38c9347b34f01a67fd7206af29194d
|
|
@ -1 +1 @@
|
|||
d9ca56584f41cdc53df610c01b375de066b4844b
|
||||
133130a8ae8d6597399a7de05ba9b63ee55f5e2d
|
|
@ -132,6 +132,7 @@ platform/CCThread.cpp \
|
|||
../base/CCValue.cpp \
|
||||
../base/etc1.cpp \
|
||||
../base/s3tc.cpp \
|
||||
../base/CCConsole.cpp \
|
||||
../math/kazmath/src/aabb.c \
|
||||
../math/kazmath/src/mat3.c \
|
||||
../math/kazmath/src/mat4.c \
|
||||
|
|
|
@ -258,7 +258,8 @@ Scheduler::Scheduler(void)
|
|||
, _updateHashLocked(false)
|
||||
, _scriptHandlerEntries(nullptr)
|
||||
{
|
||||
|
||||
// I don't expect to have more than 30 functions to all per frame
|
||||
_functionsToPerform.reserve(30);
|
||||
}
|
||||
|
||||
Scheduler::~Scheduler(void)
|
||||
|
@ -825,6 +826,15 @@ void Scheduler::resumeTargets(Set* targetsToResume)
|
|||
}
|
||||
}
|
||||
|
||||
void Scheduler::performFunctionInCocosThread(const std::function<void ()> &function)
|
||||
{
|
||||
_performMutex.lock();
|
||||
|
||||
_functionsToPerform.push_back(function);
|
||||
|
||||
_performMutex.unlock();
|
||||
}
|
||||
|
||||
// main loop
|
||||
void Scheduler::update(float dt)
|
||||
{
|
||||
|
@ -835,6 +845,10 @@ void Scheduler::update(float dt)
|
|||
dt *= _timeScale;
|
||||
}
|
||||
|
||||
//
|
||||
// Selector callbacks
|
||||
//
|
||||
|
||||
// Iterate over all the Updates' selectors
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
|
@ -904,23 +918,6 @@ void Scheduler::update(float dt)
|
|||
}
|
||||
}
|
||||
|
||||
// Iterate over all the script callbacks
|
||||
if (_scriptHandlerEntries)
|
||||
{
|
||||
for (int i = _scriptHandlerEntries->count() - 1; i >= 0; i--)
|
||||
{
|
||||
SchedulerScriptHandlerEntry* eachEntry = static_cast<SchedulerScriptHandlerEntry*>(_scriptHandlerEntries->getObjectAtIndex(i));
|
||||
if (eachEntry->isMarkedForDeletion())
|
||||
{
|
||||
_scriptHandlerEntries->removeObjectAtIndex(i);
|
||||
}
|
||||
else if (!eachEntry->isPaused())
|
||||
{
|
||||
eachEntry->getTimer()->update(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete all updates that are marked for deletion
|
||||
// updates with priority < 0
|
||||
DL_FOREACH_SAFE(_updatesNegList, entry, tmp)
|
||||
|
@ -950,8 +947,43 @@ void Scheduler::update(float dt)
|
|||
}
|
||||
|
||||
_updateHashLocked = false;
|
||||
|
||||
_currentTarget = nullptr;
|
||||
|
||||
//
|
||||
// Script callbacks
|
||||
//
|
||||
|
||||
// Iterate over all the script callbacks
|
||||
if (_scriptHandlerEntries)
|
||||
{
|
||||
for (auto i = _scriptHandlerEntries->count() - 1; i >= 0; i--)
|
||||
{
|
||||
SchedulerScriptHandlerEntry* eachEntry = static_cast<SchedulerScriptHandlerEntry*>(_scriptHandlerEntries->getObjectAtIndex(i));
|
||||
if (eachEntry->isMarkedForDeletion())
|
||||
{
|
||||
_scriptHandlerEntries->removeObjectAtIndex(i);
|
||||
}
|
||||
else if (!eachEntry->isPaused())
|
||||
{
|
||||
eachEntry->getTimer()->update(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Functions allocated from another thread
|
||||
//
|
||||
|
||||
// Testing size is faster than locking / unlocking.
|
||||
// And almost never there will be functions scheduled to be called.
|
||||
if( _functionsToPerform.size() > 0 ) {
|
||||
_performMutex.lock();
|
||||
for( const auto &function : _functionsToPerform ) {
|
||||
function();
|
||||
}
|
||||
_functionsToPerform.clear();
|
||||
_performMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ THE SOFTWARE.
|
|||
#ifndef __CCSCHEDULER_H__
|
||||
#define __CCSCHEDULER_H__
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
#include "CCObject.h"
|
||||
#include "uthash.h"
|
||||
|
||||
|
@ -257,7 +261,13 @@ public:
|
|||
*/
|
||||
void resumeTargets(Set* targetsToResume);
|
||||
|
||||
private:
|
||||
/** calls a function on the cocos2d thread. Useful when you need to call a cocos2d function from another thread.
|
||||
This function is thread safe.
|
||||
@since v3.0
|
||||
*/
|
||||
void performFunctionInCocosThread( const std::function<void()> &function);
|
||||
|
||||
protected:
|
||||
void removeHashElement(struct _hashSelectorEntry *element);
|
||||
void removeUpdateFromHash(struct _listEntry *entry);
|
||||
|
||||
|
@ -266,7 +276,7 @@ private:
|
|||
void priorityIn(struct _listEntry **list, Object *target, int priority, bool paused);
|
||||
void appendIn(struct _listEntry **list, Object *target, bool paused);
|
||||
|
||||
protected:
|
||||
|
||||
float _timeScale;
|
||||
|
||||
//
|
||||
|
@ -284,6 +294,10 @@ protected:
|
|||
// If true unschedule will not remove anything from a hash. Elements will only be marked for deletion.
|
||||
bool _updateHashLocked;
|
||||
Array* _scriptHandlerEntries;
|
||||
|
||||
// Used for "perform Function"
|
||||
std::vector<std::function<void()>> _functionsToPerform;
|
||||
std::mutex _performMutex;
|
||||
};
|
||||
|
||||
// end of global group
|
||||
|
|
|
@ -202,6 +202,7 @@ THE SOFTWARE.
|
|||
#include "ccUTF8.h"
|
||||
#include "CCNotificationCenter.h"
|
||||
#include "CCProfiling.h"
|
||||
#include "CCConsole.h"
|
||||
#include "CCUserDefault.h"
|
||||
#include "CCVertex.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,399 @@
|
|||
/****************************************************************************
|
||||
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 "CCConsole.h"
|
||||
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "CCDirector.h"
|
||||
#include "CCScheduler.h"
|
||||
|
||||
#include "CCScene.h"
|
||||
|
||||
using namespace cocos2d;
|
||||
|
||||
Console* Console::create()
|
||||
{
|
||||
auto ret = new Console;
|
||||
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Console::Console()
|
||||
: _listenfd(-1)
|
||||
, _running(false)
|
||||
, _endThread(false)
|
||||
, _commands{
|
||||
{ "fps on", [](int anFd) {
|
||||
Director *dir = Director::getInstance();
|
||||
Scheduler *sched = dir->getScheduler();
|
||||
sched->performFunctionInCocosThread( std::bind(&Director::setDisplayStats, dir, true));
|
||||
} },
|
||||
{ "fps off", [](int anFd) {
|
||||
Director *dir = Director::getInstance();
|
||||
Scheduler *sched = dir->getScheduler();
|
||||
sched->performFunctionInCocosThread( std::bind(&Director::setDisplayStats, dir, false));
|
||||
} },
|
||||
{ "scene graph", std::bind(&Console::commandSceneGraph, this, std::placeholders::_1) },
|
||||
{ "exit", std::bind(&Console::commandExit, this, std::placeholders::_1) },
|
||||
{ "help", std::bind(&Console::commandHelp, this, std::placeholders::_1) }, }
|
||||
, _maxCommands(5)
|
||||
, _userCommands(nullptr)
|
||||
, _maxUserCommands(0)
|
||||
{
|
||||
}
|
||||
|
||||
Console::~Console()
|
||||
{
|
||||
cancel();
|
||||
}
|
||||
|
||||
bool Console::listenOnTCP(int port)
|
||||
{
|
||||
int listenfd, n;
|
||||
const int on = 1;
|
||||
struct addrinfo hints, *res, *ressave;
|
||||
char serv[30];
|
||||
|
||||
snprintf(serv,sizeof(serv)-1,"%d",(unsigned int) port );
|
||||
serv[sizeof(serv)-1]=0;
|
||||
|
||||
bzero(&hints, sizeof(struct addrinfo));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
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, &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, 50);
|
||||
|
||||
if (res->ai_family == AF_INET) {
|
||||
char buf2[256] = "";
|
||||
gethostname(buf2, sizeof(buf2)-1);
|
||||
char buf[INET_ADDRSTRLEN] = "";
|
||||
struct sockaddr_in *sin = (struct sockaddr_in*) res->ai_addr;
|
||||
if( inet_ntop(res->ai_family, sin , buf, sizeof(buf)) != NULL )
|
||||
CCLOG("Console: listening on %s : %d", buf2, ntohs(sin->sin_port));
|
||||
else
|
||||
perror("inet_ntop");
|
||||
}
|
||||
|
||||
freeaddrinfo(ressave);
|
||||
|
||||
return listenOnFileDescriptor(listenfd);
|
||||
}
|
||||
|
||||
bool Console::listenOnFileDescriptor(int fd)
|
||||
{
|
||||
CCASSERT(!_running, "already running");
|
||||
_listenfd = fd;
|
||||
_thread = std::thread( std::bind( &Console::loop, this) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Console::cancel()
|
||||
{
|
||||
if( _running ) {
|
||||
_endThread = true;
|
||||
_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
void Console::setUserCommands(Command *commands, int numberOfCommands)
|
||||
{
|
||||
_userCommands = commands;
|
||||
_maxUserCommands = numberOfCommands;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// commands
|
||||
//
|
||||
|
||||
void Console::commandHelp(int fd)
|
||||
{
|
||||
const char help[] = "\nAvailable commands:\n";
|
||||
write(fd, help, sizeof(help));
|
||||
for(int i=0; i<_maxCommands; ++i) {
|
||||
write(fd,"\t",1);
|
||||
write(fd, _commands[i].name, strlen(_commands[i].name));
|
||||
write(fd,"\n",1);
|
||||
}
|
||||
|
||||
// User commands
|
||||
for(int i=0; i<_maxUserCommands; ++i) {
|
||||
write(fd,"\t",1);
|
||||
write(fd, _userCommands[i].name, strlen(_userCommands[i].name));
|
||||
write(fd,"\n",1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Console::commandExit(int fd)
|
||||
{
|
||||
FD_CLR(fd, &_read_set);
|
||||
_fds.erase(std::remove(_fds.begin(), _fds.end(), fd), _fds.end());
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static int mydprintf(int sock, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[1024];
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
return write(sock, buf, strlen(buf));
|
||||
}
|
||||
|
||||
|
||||
void printSceneGraph(int fd, Node* node, int level)
|
||||
{
|
||||
for(int i=0; i<level; ++i)
|
||||
write(fd, "-", 1);
|
||||
|
||||
mydprintf(fd, " %s: z=%d, tag=%d\n", node->description(), node->getZOrder(), node->getTag() );
|
||||
|
||||
auto children = node->getChildren();
|
||||
if( children ) {
|
||||
for(const auto& child: *children )
|
||||
printSceneGraph(fd, (Node*)child, level+1);
|
||||
}
|
||||
}
|
||||
|
||||
void printSceneGraphBoot(int fd)
|
||||
{
|
||||
write(fd,"\n",1);
|
||||
auto scene = Director::getInstance()->getRunningScene();
|
||||
printSceneGraph(fd, scene, 0);
|
||||
write(fd,"\n",1);
|
||||
}
|
||||
|
||||
void Console::commandSceneGraph(int fd)
|
||||
{
|
||||
Scheduler *sched = Director::getInstance()->getScheduler();
|
||||
sched->performFunctionInCocosThread( std::bind(&printSceneGraphBoot, fd) );
|
||||
}
|
||||
|
||||
bool Console::parseCommand(int fd)
|
||||
{
|
||||
auto r = readline(fd);
|
||||
if(r < 1)
|
||||
return false;
|
||||
|
||||
bool found=false;
|
||||
for(int i=0; i < _maxCommands; ++i) {
|
||||
if( strncmp(_buffer, _commands[i].name,strlen(_commands[i].name)) == 0 ) {
|
||||
// XXX TODO FIXME
|
||||
// Ideally this loop should execute the function in the cocos2d according to a variable
|
||||
// But clang crashes in runtime when doing that (bug in clang, not in the code).
|
||||
// So, unfortunately, the only way to fix it was to move that logic to the callback itself
|
||||
_commands[i].callback(fd);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// user commands
|
||||
for(int i=0; i < _maxUserCommands && !found; ++i) {
|
||||
if( strncmp(_buffer, _userCommands[i].name,strlen(_userCommands[i].name)) == 0 ) {
|
||||
_userCommands[i].callback(fd);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
const char err[] = "Unknown command. Type 'help' for options\n";
|
||||
write(fd, err, sizeof(err));
|
||||
}
|
||||
|
||||
sendPrompt(fd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
void Console::sendPrompt(int fd)
|
||||
{
|
||||
const char prompt[] = "\n> ";
|
||||
write(fd, prompt, sizeof(prompt));
|
||||
}
|
||||
|
||||
ssize_t Console::readline(int fd)
|
||||
{
|
||||
int maxlen = sizeof(_buffer)-1;
|
||||
ssize_t n, rc;
|
||||
char c, *ptr;
|
||||
|
||||
ptr = _buffer;
|
||||
|
||||
for( n=1; n<maxlen; n++ ) {
|
||||
if( (rc = read(fd, &c, 1 )) ==1 ) {
|
||||
*ptr++ = c;
|
||||
if( c=='\n' )
|
||||
break;
|
||||
} else if( rc == 0 ) {
|
||||
return 0;
|
||||
} else if( errno == EINTR ) {
|
||||
continue;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
void Console::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);
|
||||
|
||||
sendPrompt(fd);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop
|
||||
//
|
||||
|
||||
void Console::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 = 016000;
|
||||
|
||||
while(!_endThread) {
|
||||
|
||||
copy_set = _read_set;
|
||||
timeout_copy = timeout;
|
||||
int nready = select(_maxfd+1, ©_set, NULL, NULL, &timeout_copy);
|
||||
|
||||
if( nready == -1 ) {
|
||||
/* error ?*/
|
||||
if(errno != EINTR)
|
||||
log("Abnormal error in select()\n");
|
||||
continue;
|
||||
|
||||
} else if( nready == 0 ) {
|
||||
/* timeout ? */
|
||||
continue;
|
||||
}
|
||||
|
||||
// new client
|
||||
if(FD_ISSET(_listenfd, ©_set)) {
|
||||
addClient();
|
||||
if(--nready <= 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
// data from client
|
||||
std::vector<int> to_remove;
|
||||
for(const auto &fd: _fds) {
|
||||
if(FD_ISSET(fd,©_set)) {
|
||||
if( ! parseCommand(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 )
|
||||
close(fd);
|
||||
close(_listenfd);
|
||||
|
||||
_running = false;
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/****************************************************************************
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CCCONSOLE_H__
|
||||
#define __CCCONSOLE_H__
|
||||
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include "ccMacros.h"
|
||||
#include "CCObject.h"
|
||||
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
/** Console is helper class that lets the developer control the game from TCP connection.
|
||||
Console will spawn a new thread that will listen to a specified TCP port.
|
||||
Console has a basic token parser. Each token is associated with an std::function<void(int)>.
|
||||
If the std::function<> needs to use the cocos2d API, it needs to call
|
||||
|
||||
```
|
||||
scheduler->performFunctionInCocosThread( ... );
|
||||
```
|
||||
*/
|
||||
class CC_DLL Console : public Object
|
||||
{
|
||||
public:
|
||||
|
||||
struct Command {
|
||||
const char *name;
|
||||
const std::function<void(int)> callback;
|
||||
};
|
||||
|
||||
/** creates a new instnace of the Console */
|
||||
static Console* create();
|
||||
|
||||
/** starts listening to specifed TCP port */
|
||||
bool listenOnTCP(int port);
|
||||
|
||||
/** starts listening to specifed file descriptor */
|
||||
bool listenOnFileDescriptor(int fd);
|
||||
|
||||
/** cancels the Console. Cancel will be called at destruction time as well */
|
||||
void cancel();
|
||||
|
||||
/** sets user tokens */
|
||||
void setUserCommands( Command* commands, int numberOfCommands);
|
||||
|
||||
protected:
|
||||
Console();
|
||||
virtual ~Console();
|
||||
|
||||
void loop();
|
||||
|
||||
ssize_t readline(int fd);
|
||||
bool parseCommand(int fd);
|
||||
void sendPrompt(int fd);
|
||||
void addClient();
|
||||
|
||||
// Add commands here
|
||||
void commandHelp(int fd);
|
||||
void commandExit(int fd);
|
||||
void commandSceneGraph(int fd);
|
||||
|
||||
// file descriptor: socket, console, etc.
|
||||
int _listenfd;
|
||||
int _maxfd;
|
||||
std::vector<int> _fds;
|
||||
std::thread _thread;
|
||||
|
||||
fd_set _read_set;
|
||||
|
||||
bool _running;
|
||||
bool _endThread;
|
||||
|
||||
char _buffer[512];
|
||||
|
||||
struct Command _commands[15];
|
||||
int _maxCommands;
|
||||
struct Command *_userCommands;
|
||||
int _maxUserCommands;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(Console);
|
||||
};
|
||||
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif /* defined(__CCCONSOLE_H__) */
|
|
@ -14,6 +14,7 @@ set(COCOS_BASE_SRC
|
|||
etc1.cpp
|
||||
s3tc.cpp
|
||||
atitc.cpp
|
||||
CCConsole.cpp
|
||||
)
|
||||
|
||||
add_library(cocosbase STATIC
|
||||
|
|
|
@ -38,6 +38,7 @@ Classes/ClickAndMoveTest/ClickAndMoveTest.cpp \
|
|||
Classes/ClippingNodeTest/ClippingNodeTest.cpp \
|
||||
Classes/CocosDenshionTest/CocosDenshionTest.cpp \
|
||||
Classes/ConfigurationTest/ConfigurationTest.cpp \
|
||||
Classes/ConsoleTest/ConsoleTest.cpp \
|
||||
Classes/CurlTest/CurlTest.cpp \
|
||||
Classes/CurrentLanguageTest/CurrentLanguageTest.cpp \
|
||||
Classes/DataVisitorTest/DataVisitorTest.cpp \
|
||||
|
|
|
@ -125,6 +125,7 @@ set(SAMPLE_SRC
|
|||
Classes/SpineTest/SpineTest.cpp
|
||||
Classes/DataVisitorTest/DataVisitorTest.cpp
|
||||
Classes/ConfigurationTest/ConfigurationTest.cpp
|
||||
Classes/ConsoleTest/ConsoleTest.cpp
|
||||
Classes/controller.cpp
|
||||
Classes/testBasic.cpp
|
||||
Classes/AppDelegate.cpp
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
/****************************************************************************
|
||||
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 "ConsoleTest.h"
|
||||
#include "../testResource.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
// EaseSpriteDemo
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
|
||||
static int sceneIdx = -1;
|
||||
|
||||
static std::function<Layer*()> createFunctions[] =
|
||||
{
|
||||
CL(ConsoleTCP),
|
||||
CL(ConsoleCustomCommand),
|
||||
};
|
||||
|
||||
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
|
||||
|
||||
Layer* nextConsoleTest()
|
||||
{
|
||||
sceneIdx++;
|
||||
sceneIdx = sceneIdx % MAX_LAYER;
|
||||
|
||||
auto layer = (createFunctions[sceneIdx])();
|
||||
return layer;
|
||||
}
|
||||
|
||||
Layer* backConsoleTest()
|
||||
{
|
||||
sceneIdx--;
|
||||
int total = MAX_LAYER;
|
||||
if( sceneIdx < 0 )
|
||||
sceneIdx += total;
|
||||
|
||||
auto layer = (createFunctions[sceneIdx])();
|
||||
return layer;
|
||||
}
|
||||
|
||||
Layer* restartConsoleTest()
|
||||
{
|
||||
auto layer = (createFunctions[sceneIdx])();
|
||||
return layer;
|
||||
}
|
||||
|
||||
|
||||
BaseTestConsole::BaseTestConsole()
|
||||
{
|
||||
}
|
||||
|
||||
BaseTestConsole::~BaseTestConsole(void)
|
||||
{
|
||||
}
|
||||
|
||||
std::string BaseTestConsole::title()
|
||||
{
|
||||
return "No title";
|
||||
}
|
||||
|
||||
void BaseTestConsole::onEnter()
|
||||
{
|
||||
BaseTest::onEnter();
|
||||
}
|
||||
|
||||
void BaseTestConsole::restartCallback(Object* sender)
|
||||
{
|
||||
auto s = new ConsoleTestScene();
|
||||
s->addChild(restartConsoleTest());
|
||||
|
||||
Director::getInstance()->replaceScene(s);
|
||||
s->release();
|
||||
}
|
||||
|
||||
void BaseTestConsole::nextCallback(Object* sender)
|
||||
{
|
||||
auto s = new ConsoleTestScene();
|
||||
s->addChild( nextConsoleTest() );
|
||||
Director::getInstance()->replaceScene(s);
|
||||
s->release();
|
||||
}
|
||||
|
||||
void BaseTestConsole::backCallback(Object* sender)
|
||||
{
|
||||
auto s = new ConsoleTestScene();
|
||||
s->addChild( backConsoleTest() );
|
||||
Director::getInstance()->replaceScene(s);
|
||||
s->release();
|
||||
}
|
||||
|
||||
void ConsoleTestScene::runThisTest()
|
||||
{
|
||||
auto layer = nextConsoleTest();
|
||||
addChild(layer);
|
||||
|
||||
Director::getInstance()->replaceScene(this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
// ConsoleTCP
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
|
||||
ConsoleTCP::ConsoleTCP()
|
||||
{
|
||||
_console = Console::create();
|
||||
_console->retain();
|
||||
}
|
||||
|
||||
ConsoleTCP::~ConsoleTCP()
|
||||
{
|
||||
_console->release();
|
||||
}
|
||||
|
||||
void ConsoleTCP::onEnter()
|
||||
{
|
||||
BaseTestConsole::onEnter();
|
||||
_console->listenOnTCP(5678);
|
||||
}
|
||||
|
||||
std::string ConsoleTCP::title()
|
||||
{
|
||||
return "Console TCP";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
// ConsoleCustomCommand
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
|
||||
ConsoleCustomCommand::ConsoleCustomCommand()
|
||||
{
|
||||
_console = Console::create();
|
||||
_console->retain();
|
||||
|
||||
static struct Console::Command commands[] = {
|
||||
{"hello", [](int fd) {
|
||||
const char msg[] = "how are you?\n";
|
||||
write(fd, msg, sizeof(msg));
|
||||
}},
|
||||
};
|
||||
_console->setUserCommands(&commands[0],1);
|
||||
}
|
||||
|
||||
ConsoleCustomCommand::~ConsoleCustomCommand()
|
||||
{
|
||||
_console->release();
|
||||
}
|
||||
|
||||
void ConsoleCustomCommand::onEnter()
|
||||
{
|
||||
BaseTestConsole::onEnter();
|
||||
_console->listenOnTCP(5678);
|
||||
}
|
||||
|
||||
std::string ConsoleCustomCommand::title()
|
||||
{
|
||||
return "Console Custom Commands";
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/****************************************************************************
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CONSOLE_TEST_H_
|
||||
#define _CONSOLE_TEST_H_
|
||||
|
||||
////----#include "cocos2d.h"
|
||||
#include "../testBasic.h"
|
||||
#include "../BaseTest.h"
|
||||
|
||||
USING_NS_CC;
|
||||
|
||||
class BaseTestConsole : public BaseTest
|
||||
{
|
||||
public:
|
||||
BaseTestConsole();
|
||||
~BaseTestConsole();
|
||||
|
||||
virtual std::string title();
|
||||
virtual void onEnter();
|
||||
|
||||
void restartCallback(Object* sender);
|
||||
void nextCallback(Object* sender);
|
||||
void backCallback(Object* sender);
|
||||
};
|
||||
|
||||
class ConsoleTCP : public BaseTestConsole
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(ConsoleTCP);
|
||||
|
||||
void onEnter() override;
|
||||
virtual std::string title() override;
|
||||
|
||||
protected:
|
||||
ConsoleTCP();
|
||||
virtual ~ConsoleTCP();
|
||||
|
||||
cocos2d::Console *_console;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(ConsoleTCP);
|
||||
};
|
||||
|
||||
class ConsoleCustomCommand : public BaseTestConsole
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(ConsoleCustomCommand);
|
||||
|
||||
void onEnter() override;
|
||||
virtual std::string title() override;
|
||||
|
||||
protected:
|
||||
ConsoleCustomCommand();
|
||||
virtual ~ConsoleCustomCommand();
|
||||
|
||||
cocos2d::Console *_console;
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(ConsoleCustomCommand);
|
||||
};
|
||||
|
||||
class ConsoleTestScene : public TestScene
|
||||
{
|
||||
public:
|
||||
virtual void runThisTest();
|
||||
};
|
||||
|
||||
#endif // _CONSOLE_TEST_H_
|
|
@ -1 +1 @@
|
|||
9019076e23d685080a41fb65944f914bb9268c97
|
||||
e4cdac1cca25440803dbf150fc336b61c44edb93
|
|
@ -1,3 +1,27 @@
|
|||
/****************************************************************************
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SPRITE_TEST_H_
|
||||
#define _SPRITE_TEST_H_
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ struct {
|
|||
#endif
|
||||
{ "CocosDenshionTest", []() { return new CocosDenshionTestScene(); } },
|
||||
{ "ConfigurationTest", []() { return new ConfigurationTestScene(); } },
|
||||
{ "ConsoleTest", []() { return new ConsoleTestScene(); } },
|
||||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_EMSCRIPTEN)
|
||||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_NACL)
|
||||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _TESTS_H_
|
||||
#define _TESTS_H_
|
||||
|
||||
#include "ConsoleTest/ConsoleTest.h"
|
||||
#include "NewEventDispatcherTest/NewEventDispatcherTest.h"
|
||||
#include "ActionsTest/ActionsTest.h"
|
||||
#include "TransitionsTest/TransitionsTest.h"
|
||||
|
|
Loading…
Reference in New Issue