add new lua runtime

This commit is contained in:
yinjimmy 2014-12-27 02:21:55 +08:00
parent f01cc596a3
commit 4280ffcf58
87 changed files with 9282 additions and 833 deletions

View File

@ -7,6 +7,13 @@
#include "ConfigParser.h"
#include "lua_module_register.h"
#include "cocostudio/CocoStudio.h"
#if ((CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC))
#include "service/DeviceEx.h"
#include "network/CCHTTPRequest.h"
#endif
using namespace CocosDenshion;
USING_NS_CC;
@ -41,27 +48,15 @@ void AppDelegate::initGLContextAttrs()
bool AppDelegate::applicationDidFinishLaunching()
{
#if (COCOS2D_DEBUG > 0 && CC_CODE_IDE_DEBUG_SUPPORT > 0)
// NOTE:Please don't remove this call if you want to debug with Cocos Code IDE
initRuntime();
//
#if ((CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) && (CC_TARGET_PLATFORM != CC_PLATFORM_MAC) && (CC_CODE_IDE_DEBUG_SUPPORT > 0))
_project.setDebuggerType(kCCRuntimeDebuggerCodeIDE);
#endif
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
Size viewSize = ConfigParser::getInstance()->getInitViewSize();
string title = ConfigParser::getInstance()->getInitViewName();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_MAC) && (COCOS2D_DEBUG > 0 && CC_CODE_IDE_DEBUG_SUPPORT > 0)
extern void createSimulator(const char* viewName, float width, float height, bool isLandscape = true, float frameZoomFactor = 1.0f);
bool isLanscape = ConfigParser::getInstance()->isLanscape();
createSimulator(title.c_str(),viewSize.width,viewSize.height, isLanscape);
#else
glview = cocos2d::GLViewImpl::createWithRect(title.c_str(), Rect(0, 0, viewSize.width, viewSize.height));
director->setOpenGLView(glview);
#endif
}
// set default FPS
Director::getInstance()->setAnimationInterval(1.0 / 60.0f);
// register lua module
auto engine = LuaEngine::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(engine);
lua_State* L = engine->getLuaStack()->getLuaState();
@ -77,13 +72,10 @@ bool AppDelegate::applicationDidFinishLaunching()
//LuaStack* stack = engine->getLuaStack();
//register_custom_function(stack->getLuaState());
#if (COCOS2D_DEBUG > 0 && CC_CODE_IDE_DEBUG_SUPPORT > 0)
// NOTE:Please don't remove this call if you want to debug with Cocos Code IDE
startRuntime();
#else
engine->executeScriptFile(ConfigParser::getInstance()->getEntryFile().c_str());
#endif
StartupCall *call = StartupCall::create(this);
call->startup();
cocos2d::log("iShow!");
return true;
}
@ -102,3 +94,291 @@ void AppDelegate::applicationWillEnterForeground()
SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
void AppDelegate::setProjectConfig(const ProjectConfig& project)
{
_project = project;
}
void AppDelegate::reopenProject()
{
auto fileUtils = FileUtils::getInstance();
//
// set root path
// set search root **MUST** before set search paths
//
fileUtils->setDefaultResourceRootPath(_project.getProjectDir());
// clean
Director::getInstance()->getTextureCache()->removeAllTextures();
Director::getInstance()->purgeCachedData();
SimpleAudioEngine::getInstance()->stopAllEffects();
SimpleAudioEngine::getInstance()->stopBackgroundMusic(true);
vector<string> searchPaths;
fileUtils->setSearchPaths(searchPaths);
const string writablePath = _project.getWritableRealPath();
if (writablePath.length())
{
FileUtils::getInstance()->setWritablePath(writablePath.c_str());
}
resetDesignResolution();
StartupCall *call = StartupCall::create(this);
call->startup();
}
// ----------------------------------------
StartupCall *StartupCall::create(AppDelegate *app)
{
StartupCall *call = new StartupCall();
call->_app = app;
call->autorelease();
return call;
}
StartupCall::StartupCall()
: _launchEvent("empty")
{
}
static bool endWithString(const std::string &buf, const std::string &suffix)
{
return ((buf.find(suffix) + suffix.length()) == buf.length());
}
void StartupCall::startup()
{
auto engine = LuaEngine::getInstance();
auto stack = engine->getLuaStack();
const ProjectConfig &project = _app->_project;
// set search path
string path = FileUtils::getInstance()->fullPathForFilename(project.getScriptFileRealPath().c_str());
size_t pos;
while ((pos = path.find_first_of("\\")) != std::string::npos)
{
path.replace(pos, 1, "/");
}
size_t p = path.find_last_of("/");
string workdir;
if (p != path.npos)
{
workdir = path.substr(0, p);
stack->addSearchPath(workdir.c_str());
FileUtils::getInstance()->addSearchPath(workdir);
}
// update search pathes
FileUtils::getInstance()->addSearchPath(project.getProjectDir());
auto &customizedPathes = project.getSearchPath();
for (auto &path : customizedPathes)
{
FileUtils::getInstance()->addSearchPath(path);
}
updateConfigParser(project);
if (FileUtils::getInstance()->isFileExist(path))
{
updatePreviewFuncForPath(path);
// launch
if (project.getDebuggerType() == kCCRuntimeDebuggerNone)
{
_previewFunc(path);
}
else
{
// NOTE:Please don't remove this call if you want to debug with Cocos Code IDE
initRuntime(project.getProjectDir());
startRuntime();
}
}
else
{
CCLOG("[ERROR]: %s is not exist.", path.c_str());
}
// track start event
trackLaunchEvent();
}
// *NOTE*
// track event on windows / mac platform
//
void StartupCall::trackEvent(const char *eventName)
{
#if ((CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC))
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
const char *platform = "win";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
const char *platform = "mac";
#else
const char *platform = "UNKNOWN";
#endif
auto request = extra::HTTPRequest::createWithUrl(NULL,
"http://www.google-analytics.com/collect",
kCCHTTPRequestMethodPOST);
request->addPOSTValue("v", "1");
request->addPOSTValue("tid", "UA-55061270-1");
request->addPOSTValue("cid", player::DeviceEx::getInstance()->getUserGUID().c_str());
request->addPOSTValue("t", "event");
request->addPOSTValue("an", "simulator");
request->addPOSTValue("av", cocos2dVersion());
request->addPOSTValue("ec", platform);
request->addPOSTValue("ea", eventName);
request->start();
#endif // ((CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC))
}
void StartupCall::trackLaunchEvent()
{
trackEvent(_launchEvent.c_str());
}
void StartupCall::onPreviewCocosCSD(const std::string &path)
{
std::string filepath = path;
if (filepath.empty())
{
filepath = ConfigParser::getInstance()->getEntryFile();
}
CCLOG("------------------------------------------------");
CCLOG("LOAD Cocos Studio FILE (.csd): %s", filepath.c_str());
CCLOG("------------------------------------------------");
auto node = CSLoader::getInstance()->createNodeWithFlatBuffersForSimulator(filepath.c_str());
auto action = cocostudio::timeline::ActionTimelineCache::getInstance()->createActionWithFlatBuffersForSimulator(filepath.c_str());
if (action)
{
node->runAction(action);
action->gotoFrameAndPlay(0);
}
if (node)
{
if (Director::getInstance()->getRunningScene())
{
auto scene = Scene::create();
scene->addChild(node);
Director::getInstance()->replaceScene(scene);
}
else
{
auto scene = Scene::create();
scene->addChild(node);
Director::getInstance()->runWithScene(scene);
}
}
}
void StartupCall::onPreviewCocosCSB(const std::string &path)
{
std::string filepath = path;
if (filepath.empty())
{
filepath = ConfigParser::getInstance()->getEntryFile();
}
CCLOG("\n------------------------------------------------\n");
CCLOG("[WARNING]: using **SUITABLE** Cocos Studio generate csb file!!");
CCLOG("LOAD Cocos Studio FILE (.csb): %s", filepath.c_str());
CCLOG("\n------------------------------------------------\n");
auto node = CSLoader::getInstance()->createNode(filepath);
if (node)
{
if (Director::getInstance()->getRunningScene())
{
auto scene = Scene::create();
scene->addChild(node);
Director::getInstance()->replaceScene(scene);
}
else
{
auto scene = Scene::create();
scene->addChild(node);
Director::getInstance()->runWithScene(scene);
}
}
}
void StartupCall::onPreviewLua(const std::string &path)
{
CCLOG("------------------------------------------------");
CCLOG("LOAD Lua FILE: %s", path.c_str());
CCLOG("------------------------------------------------");
LuaEngine::getInstance()->executeScriptFile(path.c_str());
}
void StartupCall::onPreviewJs(const std::string &path)
{
CCLOG("------------------------------------------------");
CCLOG("LOAD Js FILE: %s", path.c_str());
CCLOG("------------------------------------------------");
CCLOG("TODO: ");
}
void StartupCall::updateConfigParser(const ProjectConfig& project)
{
// set entry file
auto parser = ConfigParser::getInstance();
string entryFile(project.getScriptFileRealPath());
if (entryFile.find(project.getProjectDir()) != string::npos)
{
entryFile.erase(0, project.getProjectDir().length());
}
entryFile = replaceAll(entryFile, "\\", "/");
parser->setEntryFile(entryFile);
parser->setBindAddress(project.getBindAddress());
}
void StartupCall::updatePreviewFuncForPath(const std::string &path)
{
// set loader
_previewFunc = [](const std::string &path) { CCLOG("[WARNING]: unsupport %s", path.c_str()); };
if (!FileUtils::getInstance()->isFileExist(path))
{
CCLOG("[ERROR]: %s is not exist.", path.c_str());
return ;
}
if (endWithString(path, ".lua"))
{
_launchEvent = "lua";
_previewFunc = std::bind(&StartupCall::onPreviewLua, this, std::placeholders::_1);
setLoader(std::bind(&luaScriptLoader, std::placeholders::_1));
}
else if (endWithString(path, ".csd"))
{
_launchEvent = "ccs";
_previewFunc = std::bind(&StartupCall::onPreviewCocosCSD, this, std::placeholders::_1);
setLoader(std::bind(&StartupCall::onPreviewCocosCSD, this, std::placeholders::_1));
}
else if (endWithString(path, ".csb"))
{
_launchEvent = "ccs";
_previewFunc = std::bind(&StartupCall::onPreviewCocosCSB, this, std::placeholders::_1);
setLoader(std::bind(&StartupCall::onPreviewCocosCSB, this, std::placeholders::_1));
}
else if (endWithString(path, ".js"))
{
_launchEvent = "js";
_previewFunc = std::bind(&StartupCall::onPreviewJs, this, std::placeholders::_1);
}
}

View File

@ -2,6 +2,8 @@
#define __APP_DELEGATE_H__
#include "cocos2d.h"
#include "ProjectConfig/ProjectConfig.h"
#include "ProjectConfig/SimulatorConfig.h"
/**
@brief The cocos2d Application.
@ -34,6 +36,42 @@ public:
@param the pointer of the application
*/
virtual void applicationWillEnterForeground();
void setProjectConfig(const ProjectConfig& project);
void reopenProject();
private:
ProjectConfig _project;
friend class StartupCall;
};
class StartupCall : public cocos2d::Ref
{
public:
static StartupCall *create(AppDelegate *app);
void startup();
private:
StartupCall();
void trackEvent(const char *eventName);
void trackLaunchEvent();
void onPreviewCocosCSD(const std::string &path);
void onPreviewCocosCSB(const std::string &path);
void onPreviewLua(const std::string &path);
void onPreviewJs(const std::string &path);
void updateConfigParser(const ProjectConfig& project);
void updatePreviewFuncForPath(const std::string &path);
private:
AppDelegate *_app;
std::function<void(const std::string &)> _previewFunc;
std::string _launchEvent;
};
#endif // __APP_DELEGATE_H__

View File

@ -6,12 +6,6 @@
#include "ConfigParser.h"
#include "FileServer.h"
#define CONFIG_FILE "config.json"
#define CONSOLE_PORT 6010
#define UPLOAD_PORT 6020
#define WIN_WIDTH 960
#define WIN_HEIGHT 640
// ConfigParser
ConfigParser *ConfigParser::s_sharedConfigParserInstance = NULL;
ConfigParser *ConfigParser::getInstance(void)
@ -19,7 +13,6 @@ ConfigParser *ConfigParser::getInstance(void)
if (!s_sharedConfigParserInstance)
{
s_sharedConfigParserInstance = new ConfigParser();
s_sharedConfigParserInstance->readConfig();
}
return s_sharedConfigParserInstance;
}
@ -29,8 +22,10 @@ void ConfigParser::purge()
CC_SAFE_DELETE(s_sharedConfigParserInstance);
}
void ConfigParser::readConfig()
void ConfigParser::readConfig(const string &filepath)
{
string fullPathFile = filepath;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// add writable path to search path temporarily for reading config file
vector<std::string> searchPathArray = FileUtils::getInstance()->getSearchPaths();
@ -39,7 +34,10 @@ void ConfigParser::readConfig()
#endif
// read config file
string fullPathFile = FileUtils::getInstance()->fullPathForFilename(CONFIG_FILE);
if (fullPathFile.empty())
{
fullPathFile = FileUtils::getInstance()->fullPathForFilename(CONFIG_FILE);
}
string fileContent = FileUtils::getInstance()->getStringFromFile(fullPathFile);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
@ -83,19 +81,19 @@ void ConfigParser::readConfig()
}
if (objectInitView.HasMember("entry") && objectInitView["entry"].IsString())
{
_entryfile = objectInitView["entry"].GetString();
setEntryFile(objectInitView["entry"].GetString());
}
if (objectInitView.HasMember("consolePort"))
{
_consolePort = objectInitView["consolePort"].GetUint();
if(_consolePort <= 0)
_consolePort = CONSOLE_PORT;
_consolePort = kProjectConfigConsolePort;
}
if (objectInitView.HasMember("uploadPort"))
{
_uploadPort = objectInitView["uploadPort"].GetUint();
if(_uploadPort <= 0)
_uploadPort = UPLOAD_PORT;
_uploadPort = kProjectConfigUploadPort;
}
if (objectInitView.HasMember("isWindowTop") && objectInitView["isWindowTop"].IsBool())
{
@ -123,11 +121,12 @@ void ConfigParser::readConfig()
ConfigParser::ConfigParser(void) :
_isLandscape(true),
_isWindowTop(false),
_consolePort(CONSOLE_PORT),
_uploadPort(UPLOAD_PORT),
_viewName("HelloLua"),
_consolePort(kProjectConfigConsolePort),
_uploadPort(kProjectConfigUploadPort),
_viewName("simulator"),
_entryfile("src/main.lua"),
_initViewSize(WIN_WIDTH, WIN_HEIGHT)
_initViewSize(ProjectConfig::DEFAULT_HEIGHT, ProjectConfig::DEFAULT_WIDTH),
_bindAddress("")
{
}
@ -160,6 +159,14 @@ bool ConfigParser::isWindowTop()
{
return _isWindowTop;
}
void ConfigParser::setConsolePort(int port)
{
_consolePort = port;
}
void ConfigParser::setUploadPort(int port)
{
_uploadPort = port;
}
int ConfigParser::getConsolePort()
{
return _consolePort;
@ -177,3 +184,23 @@ const SimulatorScreenSize ConfigParser::getScreenSize(int index)
{
return _screenSizeArray.at(index);
}
void ConfigParser::setEntryFile(const std::string &file)
{
_entryfile = file;
}
void ConfigParser::setInitViewSize(const cocos2d::Size &size)
{
_initViewSize = size;
}
void ConfigParser::setBindAddress(const std::string &address)
{
_bindAddress = address;
}
const std::string &ConfigParser::getBindAddress()
{
return _bindAddress;
}

View File

@ -5,22 +5,12 @@
#include <vector>
#include "cocos2d.h"
#include "json/document.h"
#include "ProjectConfig/SimulatorConfig.h"
#include "ProjectConfig/ProjectConfig.h"
using namespace std;
USING_NS_CC;
// ConfigParser
typedef struct _SimulatorScreenSize {
string title;
int width;
int height;
_SimulatorScreenSize(const string title_, int width_, int height_)
{
title = title_;
width = width_;
height = height_;
}
} SimulatorScreenSize;
#define CONFIG_FILE "config.json"
typedef vector<SimulatorScreenSize> ScreenSizeArray;
class ConfigParser
@ -28,6 +18,7 @@ class ConfigParser
public:
static ConfigParser *getInstance(void);
static void purge();
void readConfig(const string &filepath = "");
// predefined screen size
int getScreenSizeCount(void);
@ -36,13 +27,19 @@ public:
string getEntryFile();
rapidjson::Document& getConfigJsonRoot();
const SimulatorScreenSize getScreenSize(int index);
void setConsolePort(int port);
void setUploadPort(int port);
int getConsolePort();
int getUploadPort();
bool isLanscape();
bool isWindowTop();
void setEntryFile(const std::string &file);
void setInitViewSize(const cocos2d::Size &size);
void setBindAddress(const std::string &address);
const std::string &getBindAddress();
private:
void readConfig();
ConfigParser(void);
static ConfigParser *s_sharedConfigParserInstance;
ScreenSizeArray _screenSizeArray;
@ -53,6 +50,7 @@ private:
bool _isWindowTop;
int _consolePort;
int _uploadPort;
string _bindAddress;
rapidjson::Document _docRootjson;
};

View File

@ -0,0 +1,791 @@
#include <sstream>
#include "ProjectConfig/ProjectConfig.h"
#include "ProjectConfig/SimulatorConfig.h"
#ifdef _MSC_VER
#define strcasecmp _stricmp
#endif
#if defined(_WINDOWS)
#define DIRECTORY_SEPARATOR "\\"
#define DIRECTORY_SEPARATOR_CHAR '\\'
#else
#define DIRECTORY_SEPARATOR "/"
#define DIRECTORY_SEPARATOR_CHAR '/'
#endif
static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
static std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
ProjectConfig::ProjectConfig()
: _scriptFile("$(PROJDIR)/src/main.lua")
, _writablePath("")
, _packagePath("")
, _frameSize(960, 640)
, _frameScale(1.0f)
, _showConsole(true)
, _loadPrecompiledFramework(false)
, _writeDebugLogToFile(false)
, _windowOffset(0, 0)
, _debuggerType(kCCRuntimeDebuggerNone)
, _isAppMenu(true)
, _isResizeWindow(false)
, _isRetinaDisplay(false)
, _debugLogFile("debug.log")
, _consolePort(kProjectConfigConsolePort)
, _fileUploadPort(kProjectConfigUploadPort)
, _bindAddress("")
{
normalize();
}
string ProjectConfig::getProjectDir() const
{
return _projectDir;
}
void ProjectConfig::setProjectDir(const string &projectDir)
{
_projectDir = projectDir;
normalize();
}
string ProjectConfig::getScriptFile() const
{
return _scriptFile;
}
string ProjectConfig::getScriptFileRealPath() const
{
return replaceProjectDirToFullPath(_scriptFile);
}
void ProjectConfig::setScriptFile(const string &scriptFile)
{
_scriptFile = scriptFile;
normalize();
}
string ProjectConfig::getWritablePath() const
{
return _writablePath;
}
string ProjectConfig::getWritableRealPath() const
{
return replaceProjectDirToFullPath(_writablePath);
}
void ProjectConfig::setWritablePath(const string &writablePath)
{
_writablePath = writablePath;
normalize();
}
string ProjectConfig::getPackagePath() const
{
return _packagePath;
}
string ProjectConfig::getNormalizedPackagePath() const
{
// replace $(PROJDIR)
auto path = _packagePath;
auto pos = string::npos;
while ((pos = path.find("$(PROJDIR)")) != string::npos)
{
path = path.substr(0, pos) + _projectDir + path.substr(pos + 10);
}
auto len = path.length();
if (len && path[len - 1] != ';')
{
path.append(";");
}
path.append(";");
SimulatorConfig::makeNormalizePath(&path, "/");
return path;
}
void ProjectConfig::setPackagePath(const string &packagePath)
{
_packagePath = packagePath;
}
void ProjectConfig::addPackagePath(const string &packagePath)
{
if (packagePath.length())
{
if (_packagePath.length())
{
_packagePath.append(";");
}
_packagePath.append(packagePath);
normalize();
}
}
vector<string> ProjectConfig::getPackagePathArray() const
{
vector<string> arr;
size_t pos = string::npos;
size_t prev = 0;
while ((pos = _packagePath.find_first_of(";", pos + 1)) != string::npos)
{
auto path = _packagePath.substr(prev, pos - prev);
if (path.length() > 0) arr.push_back(path);
prev = pos + 1;
}
auto path = _packagePath.substr(prev);
if (path.length() > 0) arr.push_back(path);
return arr;
}
cocos2d::Size ProjectConfig::getFrameSize() const
{
return _frameSize;
}
void ProjectConfig::setFrameSize(const cocos2d::Size &frameSize)
{
if (frameSize.width > 0 && frameSize.height > 0)
{
_frameSize = frameSize;
}
}
bool ProjectConfig::isLandscapeFrame() const
{
return _frameSize.width > _frameSize.height;
}
bool ProjectConfig::isPortraitFrame() const
{
return _frameSize.width < _frameSize.height;
}
void ProjectConfig::changeFrameOrientation()
{
float w = _frameSize.width;
_frameSize.width = _frameSize.height;
_frameSize.height = w;
}
void ProjectConfig::changeFrameOrientationToPortait()
{
if (isLandscapeFrame()) changeFrameOrientation();
}
void ProjectConfig::changeFrameOrientationToLandscape()
{
if (!isLandscapeFrame()) changeFrameOrientation();
}
float ProjectConfig::getFrameScale() const
{
return _frameScale;
}
void ProjectConfig::setFrameScale(float frameScale)
{
if (frameScale > 0)
{
_frameScale = frameScale;
}
}
bool ProjectConfig::isShowConsole() const
{
return _showConsole;
}
void ProjectConfig::setShowConsole(bool showConsole)
{
_showConsole = showConsole;
}
bool ProjectConfig::isLoadPrecompiledFramework() const
{
return _loadPrecompiledFramework;
}
void ProjectConfig::setLoadPrecompiledFramework(bool load)
{
_loadPrecompiledFramework = load;
}
bool ProjectConfig::isWriteDebugLogToFile() const
{
return _writeDebugLogToFile;
}
void ProjectConfig::setWriteDebugLogToFile(bool writeDebugLogToFile)
{
_writeDebugLogToFile = writeDebugLogToFile;
}
void ProjectConfig::setDebugLogFilePath(const std::string &logFile)
{
_debugLogFile = logFile;
}
string ProjectConfig::getDebugLogFilePath() const
{
if (isAbsolutePath(_debugLogFile)) return _debugLogFile;
auto path(getProjectDir());
path.append(_debugLogFile);
return path;
}
cocos2d::Vec2 ProjectConfig::getWindowOffset() const
{
return _windowOffset;
}
void ProjectConfig::setWindowOffset(const cocos2d::Vec2 &windowOffset)
{
_windowOffset = windowOffset;
}
int ProjectConfig::getDebuggerType() const
{
return _debuggerType;
}
void ProjectConfig::setDebuggerType(int debuggerType)
{
_debuggerType = debuggerType;
}
void ProjectConfig::parseCommandLine(const vector<string> &args)
{
auto it = args.begin();
while (it != args.end())
{
string arg = *it;
if (arg.compare("-workdir") == 0)
{
++it;
if (it == args.end()) break;
setProjectDir(*it);
if (_writablePath.length() == 0) setWritablePath(*it);
}
else if (arg.compare("-writable-path") == 0)
{
++it;
if (it == args.end()) break;
setWritablePath(*it);
}
else if (arg.compare("-entry") == 0)
{
++it;
if (it == args.end()) break;
setScriptFile(*it);
}
else if (arg.compare("-landscape") == 0)
{
setFrameSize(cocos2d::Size(DEFAULT_HEIGHT, DEFAULT_WIDTH));
}
else if (arg.compare("-portrait") == 0)
{
setFrameSize(cocos2d::Size(DEFAULT_WIDTH, DEFAULT_HEIGHT));
}
else if (arg.compare("-resolution") == 0)
{
++it;
if (it == args.end()) break;
const string& sizeStr(*it);
size_t pos = sizeStr.find('x');
int width = 0;
int height = 0;
if (pos != sizeStr.npos && pos > 0)
{
string widthStr, heightStr;
widthStr.assign(sizeStr, 0, pos);
heightStr.assign(sizeStr, pos + 1, sizeStr.length() - pos);
width = atoi(widthStr.c_str());
height = atoi(heightStr.c_str());
setFrameSize(cocos2d::Size(width, height));
}
}
else if (arg.compare("-scale") == 0)
{
++it;
if (it == args.end()) break;
float scale = atof((*it).c_str());
setFrameScale(scale);
}
else if (arg.compare("-write-debug-log") == 0)
{
++it;
if (it == args.end()) break;
setDebugLogFilePath((*it));
setWriteDebugLogToFile(true);
}
else if (arg.compare("-console") == 0)
{
++it;
if (it == args.end()) break;
if ((*it).compare("enable") == 0)
{
setShowConsole(true);
}
else
{
setShowConsole(false);
}
}
else if (arg.compare("-position") == 0)
{
++it;
if (it == args.end()) break;
const string& posStr(*it);
size_t pos = posStr.find(',');
int x = 0;
int y = 0;
if (pos != posStr.npos && pos > 0)
{
string xStr, yStr;
xStr.assign(posStr, 0, pos);
yStr.assign(posStr, pos + 1, posStr.length() - pos);
x = atoi(xStr.c_str());
y = atoi(yStr.c_str());
setWindowOffset(cocos2d::Vec2(x, y));
}
}
else if (arg.compare("-debugger") == 0)
{
++it;
if (it == args.end()) break;
if ((*it).compare("codeide") == 0)
{
setDebuggerType(kCCRuntimeDebuggerCodeIDE);
}
else if ((*it).compare("studio") == 0)
{
setDebuggerType(kCCRuntimeDebuggerStudio);
}
}
else if (arg.compare("-app-menu") == 0)
{
_isAppMenu = true;
}
else if (arg.compare("-resize-window") == 0)
{
_isResizeWindow = true;
}
else if (arg.compare("-retina-display") == 0)
{
_isRetinaDisplay = true;
}
else if (arg.compare("-port") == 0)
{
CCLOG("TODO:");
}
else if (arg.compare("-listen") == 0)
{
++it;
setBindAddress((*it));
}
else if (arg.compare("-search-path") == 0)
{
++it;
vector<string> pathes = split((*it), ';');
setSearchPath(pathes);
}
++it;
}
}
string ProjectConfig::makeCommandLine(unsigned int mask /* = kProjectConfigAll */) const
{
stringstream buff;
vector<string> commands = makeCommandLineVector(mask);
for (auto &cmd : commands)
{
buff << " " << cmd;
}
string result = buff.str();
while (result.at(0) == ' ')
{
result = result.assign(result, 1, result.length());
}
return result;
}
vector<string> ProjectConfig::makeCommandLineVector(unsigned int mask /* = kProjectConfigAll */) const
{
vector<string> ret;
stringstream buff;
if (mask & kProjectConfigProjectDir)
{
auto path = getProjectDir();
if (path.length())
{
ret.push_back("-workdir");
ret.push_back(dealWithSpaceWithPath(path));
}
}
if (mask & kProjectConfigScriptFile)
{
auto path = getScriptFileRealPath();
if (path.length())
{
ret.push_back("-entry");
ret.push_back(dealWithSpaceWithPath(path));
}
}
if (mask & kProjectConfigWritablePath)
{
auto path = getWritableRealPath();
if (path.length())
{
ret.push_back("-writable-path");
ret.push_back(dealWithSpaceWithPath(path));
}
}
if (mask & kProjectConfigFrameSize)
{
buff.str("");
buff << (int)getFrameSize().width;
buff << "x";
buff << (int)getFrameSize().height;
ret.push_back("-resolution");
ret.push_back(buff.str());
}
if (mask & kProjectConfigFrameScale)
{
if (getFrameScale() < 1.0f)
{
buff.str("");
buff.precision(2);
buff << getFrameScale();
ret.push_back("-scale");
ret.push_back(buff.str());
}
}
if (mask & kProjectConfigWriteDebugLogToFile)
{
if (isWriteDebugLogToFile())
{
ret.push_back("-write-debug-log");
ret.push_back(getDebugLogFilePath());
}
}
if (mask & kProjectConfigShowConsole)
{
if (isShowConsole())
{
ret.push_back("-console");
ret.push_back("enable");
}
else
{
ret.push_back("-console");
ret.push_back("disable");
}
}
if (mask & kProjectConfigWindowOffset)
{
if (_windowOffset.x != 0 && _windowOffset.y != 0)
{
buff.str("");
buff << (int)_windowOffset.x;
buff << ",";
buff << (int)_windowOffset.y;
buff << "";
ret.push_back("-position");
ret.push_back(buff.str());
}
}
if (mask & kProjectConfigDebugger)
{
switch (getDebuggerType())
{
case kCCRuntimeDebuggerCodeIDE:
ret.push_back("-debugger");
ret.push_back("codeide");
break;
case kCCRuntimeDebuggerStudio:
ret.push_back("-debugger");
ret.push_back("studio");
break;
}
}
if (mask & kProjectConfigListen)
{
if (!_bindAddress.empty())
{
ret.push_back("-listen");
ret.push_back(_bindAddress);
}
}
if (mask & kProjectConfigSearchPath)
{
if (_searchPath.size() > 0)
{
stringstream pathbuff;
for (auto &path : _searchPath)
{
pathbuff << dealWithSpaceWithPath(path) << ";";
}
string pathArgs = pathbuff.str();
pathArgs[pathArgs.length()-1] = '\0';
ret.push_back("-search-path");
ret.push_back(pathArgs);
}
}
return ret;
}
void ProjectConfig::setConsolePort(int port)
{
_consolePort = port;
}
int ProjectConfig::getConsolePort()
{
return _consolePort;
}
void ProjectConfig::setFileUploadPort(int port)
{
_fileUploadPort = port;
}
int ProjectConfig::getFileUploadPort()
{
return _fileUploadPort;
}
void ProjectConfig::setBindAddress(const std::string &address)
{
_bindAddress = address;
}
const std::string &ProjectConfig::getBindAddress() const
{
return _bindAddress;
}
void ProjectConfig::setSearchPath(const vector<string> &args)
{
_searchPath = args;
}
const vector<string> &ProjectConfig::getSearchPath() const
{
return _searchPath;
}
bool ProjectConfig::isAppMenu() const
{
return _isAppMenu;
}
bool ProjectConfig::isResizeWindow() const
{
return _isResizeWindow;
}
bool ProjectConfig::isRetinaDisplay() const
{
return _isRetinaDisplay;
}
bool ProjectConfig::validate() const
{
auto utils = cocos2d::FileUtils::getInstance();
if (!utils->isDirectoryExist(_projectDir)) return false;
if (!utils->isDirectoryExist(getWritableRealPath())) return false;
if (!utils->isFileExist(getScriptFileRealPath())) return false;
return true;
}
void ProjectConfig::dump()
{
CCLOG("Project Config:");
CCLOG(" project dir: %s", _projectDir.c_str());
CCLOG(" writable path: %s", _writablePath.length() ? _writablePath.c_str() : "-");
CCLOG(" script file: %s", _scriptFile.c_str());
CCLOG(" frame size: %0.0f x %0.0f", _frameSize.width, _frameSize.height);
CCLOG(" frame scale: %0.2f", _frameScale);
CCLOG(" show console: %s", _showConsole ? "YES" : "NO");
CCLOG(" write debug log: %s (%s)", _writeDebugLogToFile ? getDebugLogFilePath().c_str() : "NO",
_writeDebugLogToFile ? getDebugLogFilePath().c_str() : "");
CCLOG(" listen: %s", _bindAddress.c_str());
if (_debuggerType == kCCRuntimeDebuggerLDT)
{
CCLOG(" debugger: Eclipse LDT");
}
else if (_debuggerType == kCCRuntimeDebuggerCodeIDE)
{
CCLOG(" debugger: Cocos Code IDE");
}
else if (_debuggerType == kCCRuntimeDebuggerStudio)
{
CCLOG(" debugger: Cocos Studio");
}
else
{
CCLOG(" debugger: none");
}
CCLOG(" add searching path:");
for (auto &path : _searchPath)
{
CCLOG(" %s", path.c_str());
}
CCLOG("\n\n");
}
void ProjectConfig::normalize()
{
SimulatorConfig::makeNormalizePath(&_projectDir);
SimulatorConfig::makeNormalizePath(&_scriptFile);
SimulatorConfig::makeNormalizePath(&_writablePath);
SimulatorConfig::makeNormalizePath(&_packagePath);
// projectDir
size_t len = _projectDir.length();
if (len > 0 && _projectDir[len - 1] != DIRECTORY_SEPARATOR_CHAR)
{
_projectDir.append(DIRECTORY_SEPARATOR);
len++;
}
// writablePath
if (len > 0 && _writablePath.length() == 0)
{
_writablePath = _projectDir;
}
len = _writablePath.length();
if (len > 0 && _writablePath[len - 1] != DIRECTORY_SEPARATOR_CHAR)
{
_writablePath.append(DIRECTORY_SEPARATOR);
}
_writablePath = replaceProjectDirToMacro(_writablePath);
// scriptFile
_scriptFile = replaceProjectDirToMacro(_scriptFile);
// package.path
vector<string> arr = getPackagePathArray();
_packagePath = string("");
for (auto it = arr.begin(); it != arr.end(); ++it)
{
string path = replaceProjectDirToMacro(*it);
_packagePath.append(path);
_packagePath.append(";");
}
if (_packagePath.length() > 0 && _packagePath[_packagePath.length() - 1] == ';')
{
_packagePath = _packagePath.substr(0, _packagePath.length() - 1);
}
}
string ProjectConfig::replaceProjectDirToMacro(const string &path) const
{
if (!isAbsolutePath(path))
{
if (path.compare(0, 10, "$(PROJDIR)") == 0) return path;
string result("$(PROJDIR)");
result.append(DIRECTORY_SEPARATOR);
result.append(path);
return result;
}
string result = path;
size_t len = _projectDir.length();
if (len > 0 && result.compare(0, len, _projectDir) == 0)
{
result = "$(PROJDIR)";
result.append(DIRECTORY_SEPARATOR);
result.append(path.substr(len));
}
return result;
}
string ProjectConfig::replaceProjectDirToFullPath(const string &path) const
{
if (isAbsolutePath(path)) return path;
if (path.length() == 0) return _projectDir;
string result = path;
if (path.compare(0, 10, "$(PROJDIR)") == 0)
{
result = _projectDir;
string suffix = path.substr(10);
if (suffix[0] == DIRECTORY_SEPARATOR_CHAR)
{
suffix = suffix.substr(1);
}
result.append(suffix);
}
return result;
}
bool ProjectConfig::isAbsolutePath(const string &path) const
{
if (DIRECTORY_SEPARATOR_CHAR == '/')
{
return path.length() > 0 && path[0] == '/';
}
return path.length() > 2 && path[1] == ':';
}
string ProjectConfig::dealWithSpaceWithPath(const string &path) const
{
#if defined(_WINDOWS)
string ret("\"");
ret += path;
if (path[path.length() - 1] == '\\')
{
ret += "\\";
}
ret += "\"";
return ret;
#else
return path;
#endif
}

View File

@ -0,0 +1,148 @@
#ifndef __PROJECT_CONFIG_H_
#define __PROJECT_CONFIG_H_
#include <string>
#include <vector>
using namespace std;
#include "cocos2d.h"
#include "CCLuaStack.h"
#define kCCRuntimeDebuggerNone 0
#define kCCRuntimeDebuggerLDT 1
#define kCCRuntimeDebuggerCodeIDE 2
#define kCCRuntimeDebuggerStudio 3
#define kProjectConfigProjectDir 1 // -workdir "PATH"
#define kProjectConfigScriptFile 2 // -script "FILENAME"
#define kProjectConfigPackagePath 4 // -package.path "PATH;PATH"
#define kProjectConfigWritablePath 8 // -writable "PATH"
#define kProjectConfigFrameSize 16 // -size 960x640
#define kProjectConfigFrameScale 32 // -scale 1.0
#define kProjectConfigShowConsole 64 // -console, -disable-console
#define kProjectConfigLoadPrecompiledFramework 128 // -load-framework, -disable-load-framework
#define kProjectConfigWriteDebugLogToFile 256 // -write-debug-log, -disable-write-debug-log
#define kProjectConfigWindowOffset 512 // -offset {0,0}
#define kProjectConfigDebugger 1024 // -debugger-ldt, -debugger-codeide, -disable-debugger
#define kProjectConfigListen 2048 //
#define kProjectConfigSearchPath 4096 //
#define kProjectConfigOpenRecent (kProjectConfigProjectDir | kProjectConfigScriptFile | kProjectConfigPackagePath | kProjectConfigWritablePath | kProjectConfigFrameSize | kProjectConfigFrameScale | kProjectConfigShowConsole | kProjectConfigLoadPrecompiledFramework | kProjectConfigWriteDebugLogToFile)
#define kProjectConfigAll (kProjectConfigProjectDir | kProjectConfigScriptFile | kProjectConfigPackagePath | kProjectConfigWritablePath | kProjectConfigFrameSize | kProjectConfigFrameScale | kProjectConfigShowConsole | kProjectConfigLoadPrecompiledFramework | kProjectConfigWriteDebugLogToFile | kProjectConfigWindowOffset | kProjectConfigDebugger | kProjectConfigListen | kProjectConfigSearchPath)
#define kProjectConfigConsolePort 6010
#define kProjectConfigUploadPort 6020
class ProjectConfig
{
public:
ProjectConfig();
static const int DEFAULT_WIDTH = 640;
static const int DEFAULT_HEIGHT = 960;
string getProjectDir() const;
void setProjectDir(const string &projectDir);
string getScriptFile() const;
string getScriptFileRealPath() const;
void setScriptFile(const string &scriptFile);
string getWritablePath() const;
string getWritableRealPath() const;
void setWritablePath(const string &writablePath);
string getPackagePath() const;
string getNormalizedPackagePath() const;
void setPackagePath(const string &packagePath);
void addPackagePath(const string &packagePath);
vector<string> getPackagePathArray() const;
cocos2d::Size getFrameSize() const;
void setFrameSize(const cocos2d::Size &frameSize);
bool isLandscapeFrame() const;
bool isPortraitFrame() const;
void changeFrameOrientation();
void changeFrameOrientationToPortait();
void changeFrameOrientationToLandscape();
float getFrameScale() const;
void setFrameScale(float frameScale);
bool isShowConsole() const;
void setShowConsole(bool showConsole);
bool isLoadPrecompiledFramework() const;
void setLoadPrecompiledFramework(bool load);
bool isWriteDebugLogToFile() const;
void setWriteDebugLogToFile(bool writeDebugLogToFile);
void setDebugLogFilePath(const std::string &logFile);
string getDebugLogFilePath() const;
cocos2d::Vec2 getWindowOffset() const;
void setWindowOffset(const cocos2d::Vec2 &windowOffset);
int getDebuggerType() const;
void setDebuggerType(int debuggerType);
void parseCommandLine(const vector<string> &args);
string makeCommandLine(unsigned int mask = kProjectConfigAll) const;
vector<string> makeCommandLineVector(unsigned int mask = kProjectConfigAll) const;
void setConsolePort(int port);
int getConsolePort();
void setFileUploadPort(int port);
int getFileUploadPort();
// @address: 127.0.0.1
void setBindAddress(const std::string &address);
const std::string &getBindAddress() const;
void setSearchPath(const vector<string> &args);
const vector<string> &getSearchPath() const;
bool isAppMenu() const;
bool isResizeWindow() const;
bool isRetinaDisplay() const;
bool validate() const;
void dump();
private:
string _projectDir;
string _scriptFile;
string _packagePath;
string _writablePath;
cocos2d::Size _frameSize;
float _frameScale;
bool _showConsole;
bool _loadPrecompiledFramework;
bool _writeDebugLogToFile;
bool _restartProcess;
cocos2d::Vec2 _windowOffset;
int _debuggerType;
bool _isAppMenu;
bool _isResizeWindow;
bool _isRetinaDisplay;
string _debugLogFile;
int _consolePort;
int _fileUploadPort;
string _bindAddress;
vector<string> _searchPath;
void normalize();
string replaceProjectDirToMacro(const string &path) const;
string replaceProjectDirToFullPath(const string &path) const;
bool isAbsolutePath(const string &path) const;
/**
* windows : Y:\Documents\CocosProjects\Cocos Project\ -> "Y:\Documents\CocosProjects\Cocos Project\\"
* other : return @path
*/
string dealWithSpaceWithPath(const string &path) const;
};
#endif // __PROJECT_CONFIG_H_

View File

@ -0,0 +1,77 @@
#include "SimulatorConfig.h"
#include <sstream>
SimulatorConfig *SimulatorConfig::_instance = NULL;
SimulatorConfig *SimulatorConfig::getInstance()
{
if (!_instance)
{
_instance = new SimulatorConfig();
}
return _instance;
}
SimulatorConfig::SimulatorConfig()
{
_screenSizeArray.push_back(SimulatorScreenSize("iPhone 3Gs (320x480)", 320, 480));
_screenSizeArray.push_back(SimulatorScreenSize("iPhone 4 (640x960)", 640, 960));
_screenSizeArray.push_back(SimulatorScreenSize("iPhone 5 (640x1136)", 640, 1136));
_screenSizeArray.push_back(SimulatorScreenSize("iPad (768x1024)", 768, 1024));
_screenSizeArray.push_back(SimulatorScreenSize("iPad Retina (1536x2048)", 1536, 2048));
_screenSizeArray.push_back(SimulatorScreenSize("Android (480x800)", 480, 800));
_screenSizeArray.push_back(SimulatorScreenSize("Android (480x854)", 480, 854));
_screenSizeArray.push_back(SimulatorScreenSize("Android (540x960)", 540, 960));
_screenSizeArray.push_back(SimulatorScreenSize("Android (600x1024)", 600, 1024));
_screenSizeArray.push_back(SimulatorScreenSize("Android (720x1280)", 720, 1280));
_screenSizeArray.push_back(SimulatorScreenSize("Android (800x1280)", 800, 1280));
_screenSizeArray.push_back(SimulatorScreenSize("Android (1080x1920)", 1080, 1920));
}
int SimulatorConfig::getScreenSizeCount() const
{
return (int)_screenSizeArray.size();
}
SimulatorScreenSize SimulatorConfig::getScreenSize(int index) const
{
return _screenSizeArray.at(index);
}
int SimulatorConfig::checkScreenSize(const cocos2d::Size &size) const
{
int width = size.width;
int height = size.height;
if (width > height)
{
int w = width;
width = height;
height = w;
}
int count = (int)_screenSizeArray.size();
for (int i = 0; i < count; ++i)
{
const SimulatorScreenSize &size = _screenSizeArray[i];
if (size.width == width && size.height == height)
{
return i;
}
}
return -1;
}
// helper
void SimulatorConfig::makeNormalizePath(string *path, const char *directorySeparator/* = NULL*/)
{
if (!directorySeparator) directorySeparator = DIRECTORY_SEPARATOR;
size_t pos = std::string::npos;
while ((pos = path->find_first_of("/\\", pos + 1)) != std::string::npos)
{
path->replace(pos, 1, directorySeparator);
}
}

View File

@ -0,0 +1,57 @@
#ifndef __SIMULATOR_CONFIG_H_
#define __SIMULATOR_CONFIG_H_
#include <string>
#include <vector>
using namespace std;
#include "cocos2d.h"
#if defined(_WINDOWS)
#define DIRECTORY_SEPARATOR "\\"
#define DIRECTORY_SEPARATOR_CHAR '\\'
#else
#define DIRECTORY_SEPARATOR "/"
#define DIRECTORY_SEPARATOR_CHAR '/'
#endif
typedef struct _SimulatorScreenSize {
string title;
int width;
int height;
_SimulatorScreenSize(const string &title_, int width_, int height_)
{
title = title_;
width = width_;
height = height_;
}
} SimulatorScreenSize;
typedef vector<SimulatorScreenSize> ScreenSizeArray;
typedef ScreenSizeArray::iterator ScreenSizeArrayIterator;
class SimulatorConfig
{
public:
static SimulatorConfig *getInstance();
// predefined screen size
int getScreenSizeCount() const;
SimulatorScreenSize getScreenSize(int index) const;
int checkScreenSize(const cocos2d::Size &size) const;
// helper
static void makeNormalizePath(string *path, const char *directorySeparator = NULL);
private:
SimulatorConfig();
static SimulatorConfig *_instance;
ScreenSizeArray _screenSizeArray;
};
#endif // __SIMULATOR_CONFIG_H_

View File

@ -0,0 +1,15 @@
#ifndef __COCOS2D_X_EXTRA_H_
#define __COCOS2D_X_EXTRA_H_
#include "cocos2d.h"
#include <string>
using namespace std;
using namespace cocos2d;
#define NS_CC_EXTRA_BEGIN namespace cocos2d { namespace extra {
#define NS_CC_EXTRA_END }}
#define USING_NS_CC_EXTRA using namespace cocos2d::extra
#endif /* __COCOS2D_X_EXTRA_H_ */

View File

@ -0,0 +1,20 @@
{
"zh-CN": {
"View": "视图(&V)",
"Exit": "退出(&X)",
"File": "文件(&F)",
"Portrait": "竖屏",
"Landscape": "横屏",
"Refresh": "刷新(重启)",
"Zoom Out": "缩放"
},
"zh-Hans": {
"View": "视图",
"Exit": "退出",
"File": "文件",
"Portrait": "竖屏",
"Landscape": "横屏",
"Refresh": "刷新(重启)",
"Zoom Out": "缩放"
}
}

View File

@ -0,0 +1,554 @@
#include "network/CCHTTPRequest.h"
#include <stdio.h>
#include <iostream>
#include <thread>
#if CC_LUA_ENGINE_ENABLED > 0
extern "C" {
#include "lua.h"
}
#include "CCLuaEngine.h"
#endif
#include <sstream>
NS_CC_EXTRA_BEGIN
unsigned int HTTPRequest::s_id = 0;
HTTPRequest *HTTPRequest::createWithUrl(HTTPRequestDelegate *delegate,
const char *url,
int method)
{
HTTPRequest *request = new HTTPRequest();
request->initWithDelegate(delegate, url, method);
request->autorelease();
return request;
}
#if CC_LUA_ENGINE_ENABLED > 0
HTTPRequest *HTTPRequest::createWithUrlLua(LUA_FUNCTION listener,
const char *url,
int method)
{
HTTPRequest *request = new HTTPRequest();
request->initWithListener(listener, url, method);
request->autorelease();
return request;
}
#endif
bool HTTPRequest::initWithDelegate(HTTPRequestDelegate *delegate, const char *url, int method)
{
_delegate = delegate;
return initWithUrl(url, method);
}
#if CC_LUA_ENGINE_ENABLED > 0
bool HTTPRequest::initWithListener(LUA_FUNCTION listener, const char *url, int method)
{
_listener = listener;
return initWithUrl(url, method);
}
#endif
bool HTTPRequest::initWithUrl(const char *url, int method)
{
CCAssert(url, "HTTPRequest::initWithUrl() - invalid url");
_curl = curl_easy_init();
curl_easy_setopt(_curl, CURLOPT_URL, url);
curl_easy_setopt(_curl, CURLOPT_USERAGENT, "libcurl");
curl_easy_setopt(_curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT);
curl_easy_setopt(_curl, CURLOPT_TIMEOUT, DEFAULT_TIMEOUT);
curl_easy_setopt(_curl, CURLOPT_NOSIGNAL, 1L);
if (method == kCCHTTPRequestMethodPOST)
{
curl_easy_setopt(_curl, CURLOPT_POST, 1L);
curl_easy_setopt(_curl, CURLOPT_COPYPOSTFIELDS, "");
}
++s_id;
// CCLOG("HTTPRequest[0x%04x] - create request with url: %s", s_id, url);
return true;
}
HTTPRequest::~HTTPRequest(void)
{
cleanup();
if (_listener)
{
#if (CC_LUA_ENGINE_ENABLED > 0)
LuaEngine::getInstance()->removeScriptHandler(_listener);
#endif
}
// CCLOG("HTTPRequest[0x%04x] - request removed", s_id);
}
void HTTPRequest::setRequestUrl(const char *url)
{
CCAssert(url, "HTTPRequest::setRequestUrl() - invalid url");
_url = url;
curl_easy_setopt(_curl, CURLOPT_URL, _url.c_str());
}
const string HTTPRequest::getRequestUrl(void)
{
return _url;
}
void HTTPRequest::addRequestHeader(const char *header)
{
CCAssert(_state == kCCHTTPRequestStateIdle, "HTTPRequest::addRequestHeader() - request not idle");
CCAssert(header, "HTTPRequest::addRequestHeader() - invalid header");
_headers.push_back(string(header));
}
void HTTPRequest::addPOSTValue(const char *key, const char *value)
{
CCAssert(_state == kCCHTTPRequestStateIdle, "HTTPRequest::addPOSTValue() - request not idle");
CCAssert(key, "HTTPRequest::addPOSTValue() - invalid key");
_postFields[string(key)] = string(value ? value : "");
}
void HTTPRequest::setPOSTData(const char *data)
{
CCAssert(_state == kCCHTTPRequestStateIdle, "HTTPRequest::setPOSTData() - request not idle");
CCAssert(data, "HTTPRequest::setPOSTData() - invalid post data");
_postFields.clear();
curl_easy_setopt(_curl, CURLOPT_POST, 1L);
curl_easy_setopt(_curl, CURLOPT_COPYPOSTFIELDS, data);
}
void HTTPRequest::addFormFile(const char *name, const char *filePath, const char *contentType)
{
curl_formadd(&_formPost, &_lastPost,
CURLFORM_COPYNAME, name,
CURLFORM_FILE, filePath,
CURLFORM_CONTENTTYPE, contentType,
CURLFORM_END);
//CCLOG("addFormFile %s %s %s", name, filePath, contentType);
}
void HTTPRequest::addFormContents(const char *name, const char *value)
{
curl_formadd(&_formPost, &_lastPost,
CURLFORM_COPYNAME, name,
CURLFORM_COPYCONTENTS, value,
CURLFORM_END);
//CCLOG("addFormContents %s %s", name, value);
}
void HTTPRequest::setCookieString(const char *cookie)
{
CCAssert(_state == kCCHTTPRequestStateIdle, "HTTPRequest::setAcceptEncoding() - request not idle");
curl_easy_setopt(_curl, CURLOPT_COOKIE, cookie ? cookie : "");
}
const string HTTPRequest::getCookieString(void)
{
CCAssert(_state == kCCHTTPRequestStateCompleted, "HTTPRequest::getResponseData() - request not completed");
return _responseCookies;
}
void HTTPRequest::setAcceptEncoding(int acceptEncoding)
{
CCAssert(_state == kCCHTTPRequestStateIdle, "HTTPRequest::setAcceptEncoding() - request not idle");
switch (acceptEncoding)
{
case kCCHTTPRequestAcceptEncodingGzip:
curl_easy_setopt(_curl, CURLOPT_ACCEPT_ENCODING, "gzip");
break;
case kCCHTTPRequestAcceptEncodingDeflate:
curl_easy_setopt(_curl, CURLOPT_ACCEPT_ENCODING, "deflate");
break;
default:
curl_easy_setopt(_curl, CURLOPT_ACCEPT_ENCODING, "identity");
}
}
void HTTPRequest::setTimeout(int timeout)
{
CCAssert(_state == kCCHTTPRequestStateIdle, "HTTPRequest::setTimeout() - request not idle");
curl_easy_setopt(_curl, CURLOPT_CONNECTTIMEOUT, timeout);
curl_easy_setopt(_curl, CURLOPT_TIMEOUT, timeout);
}
bool HTTPRequest::start(void)
{
CCAssert(_state == kCCHTTPRequestStateIdle, "HTTPRequest::start() - request not idle");
_state = kCCHTTPRequestStateInProgress;
_curlState = kCCHTTPRequestCURLStateBusy;
retain();
curl_easy_setopt(_curl, CURLOPT_HTTP_CONTENT_DECODING, 1);
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, writeDataCURL);
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, this);
curl_easy_setopt(_curl, CURLOPT_HEADERFUNCTION, writeHeaderCURL);
curl_easy_setopt(_curl, CURLOPT_WRITEHEADER, this);
curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, false);
curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, progressCURL);
curl_easy_setopt(_curl, CURLOPT_PROGRESSDATA, this);
curl_easy_setopt(_curl, CURLOPT_COOKIEFILE, "");
#ifdef _WINDOWS_
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
std::thread worker(requestCURL, this);
worker.detach();
#else
CreateThread(NULL, // default security attributes
0, // use default stack size
requestCURL, // thread function name
this, // argument to thread function
0, // use default creation flags
NULL);
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WP8
#else
pthread_create(&_thread, NULL, requestCURL, this);
pthread_detach(_thread);
#endif
Director::getInstance()->getScheduler()->scheduleUpdate(this, 0, false);
// CCLOG("HTTPRequest[0x%04x] - request start", s_id);
return true;
}
void HTTPRequest::cancel(void)
{
_delegate = NULL;
if (_state == kCCHTTPRequestStateIdle || _state == kCCHTTPRequestStateInProgress)
{
_state = kCCHTTPRequestStateCancelled;
}
}
int HTTPRequest::getState(void)
{
return _state;
}
int HTTPRequest::getResponseStatusCode(void)
{
CCAssert(_state == kCCHTTPRequestStateCompleted, "Request not completed");
return _responseCode;
}
const HTTPRequestHeaders &HTTPRequest::getResponseHeaders(void)
{
CCAssert(_state == kCCHTTPRequestStateCompleted, "HTTPRequest::getResponseHeaders() - request not completed");
return _responseHeaders;
}
const string HTTPRequest::getResponseHeadersString()
{
string buf;
for (HTTPRequestHeadersIterator it = _responseHeaders.begin(); it != _responseHeaders.end(); ++it)
{
buf.append(*it);
}
return buf;
}
const string HTTPRequest::getResponseString(void)
{
CCAssert(_state == kCCHTTPRequestStateCompleted, "HTTPRequest::getResponseString() - request not completed");
return string(_responseBuffer ? static_cast<char*>(_responseBuffer) : "");
}
void *HTTPRequest::getResponseData(void)
{
CCAssert(_state == kCCHTTPRequestStateCompleted, "HTTPRequest::getResponseData() - request not completed");
void *buff = malloc(_responseDataLength);
memcpy(buff, _responseBuffer, _responseDataLength);
return buff;
}
#if CC_LUA_ENGINE_ENABLED > 0
LUA_STRING HTTPRequest::getResponseDataLua(void)
{
CCAssert(_state == kCCHTTPRequestStateCompleted, "HTTPRequest::getResponseDataLua() - request not completed");
LuaStack *stack = LuaEngine::getInstance()->getLuaStack();
stack->clean();
stack->pushString(static_cast<char*>(_responseBuffer), (int)_responseDataLength);
return 1;
}
#endif
int HTTPRequest::getResponseDataLength(void)
{
CCAssert(_state == kCCHTTPRequestStateCompleted, "Request not completed");
return (int)_responseDataLength;
}
size_t HTTPRequest::saveResponseData(const char *filename)
{
CCAssert(_state == kCCHTTPRequestStateCompleted, "HTTPRequest::saveResponseData() - request not completed");
FILE *fp = fopen(filename, "wb");
CCAssert(fp, "HTTPRequest::saveResponseData() - open file failure");
size_t writedBytes = _responseDataLength;
if (writedBytes > 0)
{
fwrite(_responseBuffer, _responseDataLength, 1, fp);
}
fclose(fp);
return writedBytes;
}
int HTTPRequest::getErrorCode(void)
{
return _errorCode;
}
const string HTTPRequest::getErrorMessage(void)
{
return _errorMessage;
}
HTTPRequestDelegate* HTTPRequest::getDelegate(void)
{
return _delegate;
}
void HTTPRequest::checkCURLState(float dt)
{
CC_UNUSED_PARAM(dt);
if (_curlState != kCCHTTPRequestCURLStateBusy)
{
Director::getInstance()->getScheduler()->unscheduleAllForTarget(this);
release();
}
}
void HTTPRequest::update(float dt)
{
if (_state == kCCHTTPRequestStateInProgress)
{
#if CC_LUA_ENGINE_ENABLED > 0
if (_listener)
{
LuaValueDict dict;
dict["name"] = LuaValue::stringValue("progress");
dict["total"] = LuaValue::intValue((int)_dltotal);
dict["dltotal"] = LuaValue::intValue((int)_dlnow);
dict["request"] = LuaValue::ccobjectValue(this, "HTTPRequest");
LuaStack *stack = LuaEngine::getInstance()->getLuaStack();
stack->clean();
stack->pushLuaValueDict(dict);
stack->executeFunctionByHandler(_listener, 1);
}
#endif
return;
}
Director::getInstance()->getScheduler()->unscheduleAllForTarget(this);
if (_curlState != kCCHTTPRequestCURLStateIdle)
{
Director::getInstance()->getScheduler()->schedule(schedule_selector(HTTPRequest::checkCURLState), this, 0, false);
}
if (_state == kCCHTTPRequestStateCompleted)
{
// CCLOG("HTTPRequest[0x%04x] - request completed", s_id);
if (_delegate) _delegate->requestFinished(this);
}
else
{
// CCLOG("HTTPRequest[0x%04x] - request failed", s_id);
if (_delegate) _delegate->requestFailed(this);
}
#if CC_LUA_ENGINE_ENABLED > 0
if (_listener)
{
LuaValueDict dict;
switch (_state)
{
case kCCHTTPRequestStateCompleted:
dict["name"] = LuaValue::stringValue("completed");
break;
case kCCHTTPRequestStateCancelled:
dict["name"] = LuaValue::stringValue("cancelled");
break;
case kCCHTTPRequestStateFailed:
dict["name"] = LuaValue::stringValue("failed");
break;
default:
dict["name"] = LuaValue::stringValue("unknown");
}
dict["request"] = LuaValue::ccobjectValue(this, "HTTPRequest");
LuaStack *stack = LuaEngine::getInstance()->getLuaStack();
stack->clean();
stack->pushLuaValueDict(dict);
stack->executeFunctionByHandler(_listener, 1);
}
#endif
}
// instance callback
void HTTPRequest::onRequest(void)
{
if (_postFields.size() > 0)
{
curl_easy_setopt(_curl, CURLOPT_POST, 1L);
stringbuf buf;
for (Fields::iterator it = _postFields.begin(); it != _postFields.end(); ++it)
{
char *part = curl_easy_escape(_curl, it->first.c_str(), 0);
buf.sputn(part, strlen(part));
buf.sputc('=');
curl_free(part);
part = curl_easy_escape(_curl, it->second.c_str(), 0);
buf.sputn(part, strlen(part));
curl_free(part);
buf.sputc('&');
}
curl_easy_setopt(_curl, CURLOPT_COPYPOSTFIELDS, buf.str().c_str());
}
struct curl_slist *chunk = NULL;
for (HTTPRequestHeadersIterator it = _headers.begin(); it != _headers.end(); ++it)
{
chunk = curl_slist_append(chunk, (*it).c_str());
}
if (_formPost)
{
curl_easy_setopt(_curl, CURLOPT_HTTPPOST, _formPost);
}
curl_slist *cookies = NULL;
curl_easy_setopt(_curl, CURLOPT_HTTPHEADER, chunk);
CURLcode code = curl_easy_perform(_curl);
curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &_responseCode);
curl_easy_getinfo(_curl, CURLINFO_COOKIELIST, &cookies);
if (cookies)
{
struct curl_slist *nc = cookies;
stringbuf buf;
while (nc)
{
buf.sputn(nc->data, strlen(nc->data));
buf.sputc('\n');
nc = nc->next;
}
_responseCookies = buf.str();
curl_slist_free_all(cookies);
cookies = NULL;
}
curl_easy_cleanup(_curl);
_curl = NULL;
if (_formPost)
{
curl_formfree(_formPost);
_formPost = NULL;
}
curl_slist_free_all(chunk);
_errorCode = code;
_errorMessage = (code == CURLE_OK) ? "" : curl_easy_strerror(code);
_state = (code == CURLE_OK) ? kCCHTTPRequestStateCompleted : kCCHTTPRequestStateFailed;
_curlState = kCCHTTPRequestCURLStateClosed;
}
size_t HTTPRequest::onWriteData(void *buffer, size_t bytes)
{
if (_responseDataLength + bytes + 1 > _responseBufferLength)
{
_responseBufferLength += BUFFER_CHUNK_SIZE;
_responseBuffer = realloc(_responseBuffer, _responseBufferLength);
}
memcpy(static_cast<char*>(_responseBuffer) + _responseDataLength, buffer, bytes);
_responseDataLength += bytes;
static_cast<char*>(_responseBuffer)[_responseDataLength] = 0;
return bytes;
}
size_t HTTPRequest::onWriteHeader(void *buffer, size_t bytes)
{
char *headerBuffer = new char[bytes + 1];
headerBuffer[bytes] = 0;
memcpy(headerBuffer, buffer, bytes);
_responseHeaders.push_back(string(headerBuffer));
delete []headerBuffer;
return bytes;
}
int HTTPRequest::onProgress(double dltotal, double dlnow, double ultotal, double ulnow)
{
_dltotal = dltotal;
_dlnow = dlnow;
_ultotal = ultotal;
_ulnow = ulnow;
return _state == kCCHTTPRequestStateCancelled ? 1: 0;
}
void HTTPRequest::cleanup(void)
{
_state = kCCHTTPRequestStateCleared;
_responseBufferLength = 0;
_responseDataLength = 0;
if (_responseBuffer)
{
free(_responseBuffer);
_responseBuffer = NULL;
}
if (_curl)
{
curl_easy_cleanup(_curl);
_curl = NULL;
}
}
// curl callback
#ifdef _WINDOWS_
DWORD WINAPI HTTPRequest::requestCURL(LPVOID userdata)
{
static_cast<HTTPRequest*>(userdata)->onRequest();
return 0;
}
#else // _WINDOWS_
void *HTTPRequest::requestCURL(void *userdata)
{
static_cast<HTTPRequest*>(userdata)->onRequest();
return NULL;
}
#endif // _WINDOWS_
size_t HTTPRequest::writeDataCURL(void *buffer, size_t size, size_t nmemb, void *userdata)
{
return static_cast<HTTPRequest*>(userdata)->onWriteData(buffer, size *nmemb);
}
size_t HTTPRequest::writeHeaderCURL(void *buffer, size_t size, size_t nmemb, void *userdata)
{
return static_cast<HTTPRequest*>(userdata)->onWriteHeader(buffer, size *nmemb);
}
int HTTPRequest::progressCURL(void *userdata, double dltotal, double dlnow, double ultotal, double ulnow)
{
return static_cast<HTTPRequest*>(userdata)->onProgress(dltotal, dlnow, ultotal, ulnow);
}
NS_CC_EXTRA_END

View File

@ -0,0 +1,226 @@
#ifndef __CC_HTTP_REQUEST_H_
#define __CC_HTTP_REQUEST_H_
#include "cocos2dx_extra.h"
#include "cocos2d.h"
#include "network/CCHTTPRequestDelegate.h"
#if CC_LUA_ENGINE_ENABLED > 0
#include "CCLuaEngine.h"
#endif
#ifdef _WINDOWS_
#include <Windows.h>
#else
#include <pthread.h>
#endif
#include <stdio.h>
#include <vector>
#include <map>
#include <string>
#include "curl/curl.h"
using namespace std;
//USING_NS_CC;
NS_CC_EXTRA_BEGIN
#define kCCHTTPRequestMethodGET 0
#define kCCHTTPRequestMethodPOST 1
#define kCCHTTPRequestAcceptEncodingIdentity 0
#define kCCHTTPRequestAcceptEncodingGzip 1
#define kCCHTTPRequestAcceptEncodingDeflate 2
#define kCCHTTPRequestStateIdle 0
#define kCCHTTPRequestStateCleared 1
#define kCCHTTPRequestStateInProgress 2
#define kCCHTTPRequestStateCompleted 3
#define kCCHTTPRequestStateCancelled 4
#define kCCHTTPRequestStateFailed 5
#define kCCHTTPRequestCURLStateIdle 0
#define kCCHTTPRequestCURLStateBusy 1
#define kCCHTTPRequestCURLStateClosed 2
typedef vector<string> HTTPRequestHeaders;
typedef HTTPRequestHeaders::iterator HTTPRequestHeadersIterator;
class HTTPRequest : public Ref
{
public:
static HTTPRequest *createWithUrl(HTTPRequestDelegate *delegate,
const char *url,
int method = kCCHTTPRequestMethodGET);
#if CC_LUA_ENGINE_ENABLED > 0
static HTTPRequest* createWithUrlLua(LUA_FUNCTION listener,
const char *url,
int method = kCCHTTPRequestMethodGET);
#endif
~HTTPRequest(void);
/** @brief Set request url. */
void setRequestUrl(const char *url);
/** @brief Get request url. */
const string getRequestUrl(void);
/** @brief Add a custom header to the request. */
void addRequestHeader(const char *header);
/** @brief Add a POST variable to the request, POST only. */
void addPOSTValue(const char *key, const char *value);
/** @brief Set POST data to the request body, POST only. */
void setPOSTData(const char *data);
void addFormFile(const char *name, const char *filePath, const char *fileType="application/octet-stream");
void addFormContents(const char *name, const char *value);
/** @brief Set/Get cookie string. */
void setCookieString(const char *cookie);
const string getCookieString(void);
/** @brief Set accept encoding. */
void setAcceptEncoding(int acceptEncoding);
/** @brief Number of seconds to wait before timing out - default is 10. */
void setTimeout(int timeout);
/** @brief Execute an asynchronous request. */
bool start(void);
/** @brief Cancel an asynchronous request, clearing all delegates first. */
void cancel(void);
/** @brief Get the request state. */
int getState(void);
/** @brief Return HTTP status code. */
int getResponseStatusCode(void);
/** @brief Return HTTP response headers. */
const HTTPRequestHeaders &getResponseHeaders(void);
const string getResponseHeadersString(void);
/** @brief Returns the contents of the result. */
const string getResponseString(void);
/** @brief Alloc memory block, return response data. use free() release memory block */
void *getResponseData(void);
#if CC_LUA_ENGINE_ENABLED > 0
LUA_STRING getResponseDataLua(void);
#endif
/** @brief Get response data length (bytes). */
int getResponseDataLength(void);
/** @brief Save response data to file. */
size_t saveResponseData(const char *filename);
/** @brief Get error code. */
int getErrorCode(void);
/** @brief Get error message. */
const string getErrorMessage(void);
/** @brief Return HTTPRequestDelegate delegate. */
HTTPRequestDelegate* getDelegate(void);
/** @brief timer function. */
void checkCURLState(float dt);
virtual void update(float dt);
private:
HTTPRequest(void)
: _delegate(NULL)
, _listener(0)
, _state(kCCHTTPRequestStateIdle)
, _errorCode(0)
, _responseCode(0)
, _responseBuffer(NULL)
, _responseBufferLength(0)
, _responseDataLength(0)
, _curlState(kCCHTTPRequestCURLStateIdle)
, _formPost(NULL)
, _lastPost(NULL)
, _dltotal(0)
, _dlnow(0)
, _ultotal(0)
, _ulnow(0)
{
}
bool initWithDelegate(HTTPRequestDelegate* delegate, const char *url, int method);
#if CC_LUA_ENGINE_ENABLED > 0
bool initWithListener(LUA_FUNCTION listener, const char *url, int method);
#endif
bool initWithUrl(const char *url, int method);
enum {
DEFAULT_TIMEOUT = 10, // 10 seconds
BUFFER_CHUNK_SIZE = 32768, // 32 KB
};
static unsigned int s_id;
string _url;
HTTPRequestDelegate* _delegate;
int _listener;
int _curlState;
CURL *_curl;
curl_httppost *_formPost;
curl_httppost *_lastPost;
int _state;
int _errorCode;
string _errorMessage;
// request
typedef map<string, string> Fields;
Fields _postFields;
HTTPRequestHeaders _headers;
// response
int _responseCode;
HTTPRequestHeaders _responseHeaders;
void *_responseBuffer;
size_t _responseBufferLength;
size_t _responseDataLength;
string _responseCookies;
double _dltotal;
double _dlnow;
double _ultotal;
double _ulnow;
// private methods
void cleanup(void);
void cleanupRawResponseBuff(void);
// instance callback
void onRequest(void);
size_t onWriteData(void *buffer, size_t bytes);
size_t onWriteHeader(void *buffer, size_t bytes);
int onProgress(double dltotal, double dlnow, double ultotal, double ulnow);
// curl callback
#ifdef _WINDOWS_
static DWORD WINAPI requestCURL(LPVOID userdata);
#else
pthread_t _thread;
static void *requestCURL(void *userdata);
#endif
static size_t writeDataCURL(void *buffer, size_t size, size_t nmemb, void *userdata);
static size_t writeHeaderCURL(void *buffer, size_t size, size_t nmemb, void *userdata);
static int progressCURL(void *userdata, double dltotal, double dlnow, double ultotal, double ulnow);
};
NS_CC_EXTRA_END
#endif /* __CC_HTTP_REQUEST_H_ */

View File

@ -0,0 +1,20 @@
#ifndef __CC_EXTENSION_CCHTTP_REQUEST_DELEGATE_H_
#define __CC_EXTENSION_CCHTTP_REQUEST_DELEGATE_H_
#include "cocos2dx_extra.h"
NS_CC_EXTRA_BEGIN
class HTTPRequest;
class HTTPRequestDelegate
{
public:
virtual void requestFinished(HTTPRequest* request) {}
virtual void requestFailed(HTTPRequest* request) {}
};
NS_CC_EXTRA_END
#endif // __CC_EXTENSION_CCHTTP_REQUEST_DELEGATE_H_

View File

@ -127,6 +127,9 @@ void ConsoleCommand::init()
{
_console->addCommand(commands[i]);
}
// set bind address
_console->setBindAddress(ConfigParser::getInstance()->getBindAddress());
#if(CC_PLATFORM_MAC == CC_TARGET_PLATFORM || CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM)
_console->listenOnTCP(ConfigParser::getInstance()->getConsolePort());
#else
@ -162,7 +165,7 @@ void ConsoleCommand::onSendCommand(int fd, const std::string &args)
if(strcmp(strcmd.c_str(), "start-logic") == 0)
{
char szDebugArg[1024] = {0};
sprintf(szDebugArg, "require('debugger')(%s,'%s')",dArgParse["debugcfg"].GetString(), "");
snprintf(szDebugArg, sizeof(szDebugArg), "require('debugger')(%s,'%s')",dArgParse["debugcfg"].GetString(), "");
startScript(szDebugArg);
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
@ -294,6 +297,32 @@ void ConsoleCommand::onSendCommand(int fd, const std::string &args)
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
}
else if (strcmp(strcmd.c_str(), "workdir") == 0)
{
if (dArgParse.HasMember("path"))
{
const rapidjson::Value& objectPath = dArgParse["path"];
FileUtils::getInstance()->setDefaultResourceRootPath(objectPath.GetString());
rapidjson::Value bodyvalue(rapidjson::kObjectType);
bodyvalue.AddMember("path", objectPath.GetString(), dReplyParse.GetAllocator());
dReplyParse.AddMember("body", bodyvalue, dReplyParse.GetAllocator());
}
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
}
else if (strcmp(strcmd.c_str(), "writablePath") == 0)
{
if (dArgParse.HasMember("path"))
{
const rapidjson::Value& objectPath = dArgParse["path"];
FileUtils::getInstance()->setWritablePath(objectPath.GetString());
rapidjson::Value bodyvalue(rapidjson::kObjectType);
bodyvalue.AddMember("path", objectPath.GetString(), dReplyParse.GetAllocator());
dReplyParse.AddMember("body", bodyvalue, dReplyParse.GetAllocator());
}
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
}
rapidjson::StringBuffer buffer;
rapidjson::Writer< rapidjson::StringBuffer > writer(buffer);

View File

@ -25,6 +25,7 @@ THE SOFTWARE.
#include "FileServer.h"
#include "Runtime.h"
#include "zlib.h"
#include "ConfigParser.h"
// header files for directory operation
#ifdef _WIN32
@ -152,6 +153,17 @@ bool FileServer::listenOnTCP(int port)
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on));
//setsockopt(listenfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on));
auto address = ConfigParser::getInstance()->getBindAddress();
// bind address
#if ((CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32))
if (address.length() > 0)
{
struct sockaddr_in *sin = (struct sockaddr_in*) res->ai_addr;
sin->sin_addr.s_addr = inet_addr(address.c_str());
}
#endif
if (::bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)
break; /* success */

View File

@ -35,19 +35,15 @@ THE SOFTWARE.
#include <vector>
static std::string g_projectPath;
static std::function<void (std::string)> s_gProjectLoader = [](std::string path)
{
CCLOG("Please set loader for your project");
};
void startScript(std::string strDebugArg)
{
// register lua engine
auto engine = LuaEngine::getInstance();
if (!strDebugArg.empty())
{
// open debugger.lua module
cocos2d::log("debug args = %s", strDebugArg.c_str());
luaopen_lua_debugger(engine->getLuaStack()->getLuaState());
engine->executeString(strDebugArg.c_str());
}
engine->executeScriptFile(ConfigParser::getInstance()->getEntryFile().c_str());
resetDesignResolution();
s_gProjectLoader(strDebugArg);
}
@ -252,20 +248,27 @@ static void register_runtime_override_function(lua_State* tolua_S)
lua_pop(tolua_S, 1);
}
void initRuntime()
void initRuntime(const std::string& workPath)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
vector<std::string> searchPathArray = FileUtils::getInstance()->getSearchPaths();
extern std::string getCurAppPath();
std::string appPath = getCurAppPath();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
appPath.append("/../../");
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
appPath.append("/../../../");
#endif
appPath = replaceAll(appPath, "\\", "/");
g_projectPath = appPath;
if (workPath.empty())
{
extern std::string getCurAppPath();
std::string appPath = getCurAppPath();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
appPath.append("/../../");
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
appPath.append("/../../../");
#endif
appPath = replaceAll(appPath, "\\", "/");
g_projectPath = appPath;
}
else
{
g_projectPath = workPath;
}
// add project's root directory to search path
searchPathArray.insert(searchPathArray.begin(), g_projectPath);
@ -298,3 +301,34 @@ void endRuntime()
FileServer::getShareInstance()->stop();
//FileServer::purge();
}
//////////////////////// Loader ////////////////////
void setLoader(std::function<void (std::string)> func)
{
s_gProjectLoader = func;
}
void luaScriptLoader(std::string strDebugArg)
{
// register lua engine
auto engine = LuaEngine::getInstance();
if (!strDebugArg.empty())
{
// open debugger.lua module
cocos2d::log("debug args = %s", strDebugArg.c_str());
luaopen_lua_debugger(engine->getLuaStack()->getLuaState());
engine->executeString(strDebugArg.c_str());
}
std::string code("require \"");
code.append(ConfigParser::getInstance()->getEntryFile().c_str());
code.append("\"");
engine->executeString(code.c_str());
}
void resetDesignResolution()
{
cocos2d::Size size = ConfigParser::getInstance()->getInitViewSize();
Director::getInstance()->getOpenGLView()->setFrameSize(size.width, size.height);
Director::getInstance()->getOpenGLView()->setDesignResolutionSize(size.width, size.height, ResolutionPolicy::EXACT_FIT);
}

View File

@ -26,6 +26,7 @@ THE SOFTWARE.
#define _RUNTIME__H_
#include <string>
#include <functional>
void recvBuf(int fd, char *pbuf, unsigned long bufsize);
@ -39,11 +40,17 @@ const char* getRuntimeVersion();
void startScript(std::string strDebugArg);
void initRuntime();
void initRuntime(const std::string& workPath);
void startRuntime();
void endRuntime();
//
void resetDesignResolution();
const char* getRuntimeVersion();
void luaScriptLoader(std::string strDebugArg);
void setLoader(std::function<void (std::string)> func);
#endif // _RUNTIME__H_

View File

@ -0,0 +1,33 @@
//
// AppEvent.cpp
// Simulator
//
//
#include "AppEvent.h"
AppEvent::AppEvent(const std::string& eventName, int type)
: EventCustom(eventName)
, _eventName(eventName)
{
setEventType(type);
}
void AppEvent::setEventType(int type)
{
_eventType = type;
}
int AppEvent::getEventType()
{
return _eventType;
}
void AppEvent::setDataString(std::string data)
{
_dataString = data;
}
std::string AppEvent::getDataString()
{
return _dataString;
}

View File

@ -0,0 +1,47 @@
//
// AppEvent.h
// Simulator
//
//
#ifndef __Simulator__AppEvent__
#define __Simulator__AppEvent__
#include <string>
#include "cocos2d.h"
// encode / decode json
#include "json/document.h"
#include "json/filestream.h"
#include "json/stringbuffer.h"
#include "json/writer.h"
enum
{
APP_EVENT_MENU = 1,
APP_EVENT_DROP = 2
};
#define kAppEventDropName "APP.EVENT.DROP"
#define kAppEventName "APP.EVENT"
class AppEvent : public cocos2d::EventCustom
{
public:
/** Constructor */
AppEvent(const std::string& eventName, int type);
/** Gets event name */
inline const std::string& getEventName() const { return _eventName; };
void setEventType(int type);
int getEventType();
void setDataString(std::string data);
std::string getDataString();
protected:
std::string _eventName;
std::string _dataString;
int _eventType;
};
#endif /* defined(__Simulator__AppEvent__) */

View File

@ -0,0 +1,75 @@
//
// AppLang.cpp
// Simulator
//
#include "AppLang.h"
USING_NS_CC;
AppLang::AppLang()
: _hasInit(false)
{
_localizationFileName = "lang";
}
void AppLang::readLocalizationFile()
{
if (!_hasInit)
{
_hasInit = true;
std::string fullPathFile = FileUtils::getInstance()->fullPathForFilename(_localizationFileName.c_str());
if (fullPathFile.compare(_localizationFileName) == 0)
{
cocos2d::log("[WARNING]:\nnot find %s", this->_localizationFileName.c_str());
return;
}
std::string fileContent = FileUtils::getInstance()->getStringFromFile(fullPathFile);
if(fileContent.empty())
return;
if (_docRootjson.Parse<0>(fileContent.c_str()).HasParseError())
{
cocos2d::log("[WARNING]:\nread json file %s failed because of %s", fullPathFile.c_str(), _docRootjson.GetParseError());
return;
}
}
}
AppLang* AppLang::getInstance()
{
static AppLang *lang = nullptr;
if (!lang)
{
lang = new AppLang;
lang->readLocalizationFile();
}
return lang;
}
std::string AppLang::getString(const std::string &lang, const std::string &key)
{
std::string tmpKey = key;
const char *ckey = tmpKey.c_str();
std::string tmpLang = lang;
const char *langKey = tmpLang.c_str();
if (!_docRootjson.IsObject())
{
return key;
}
if (_docRootjson.HasMember(langKey))
{
const rapidjson::Value& v = _docRootjson[langKey];
if (v.HasMember(ckey))
{
std::string tmpv = v[ckey].GetString();
return v[ckey].GetString();
}
}
return key;
}

View File

@ -0,0 +1,33 @@
//
// AppLang.h
// Simulator
//
#ifndef __Simulator__AppLang__
#define __Simulator__AppLang__
#include "cocos2d.h"
#include <map>
#include "json/document.h"
#include "DeviceEx.h"
class AppLang
{
public:
static AppLang* getInstance();
std::string getString(const std::string &lang, const std::string& key);
protected:
AppLang();
void readLocalizationFile();
bool _hasInit;
std::string _localizationFileName;
rapidjson::Document _docRootjson;
};
#define tr(key) AppLang::getInstance()->getString(player::DeviceEx::getInstance()->getCurrentUILangName(), key)
#endif /* defined(__Simulator__AppLang__) */

View File

@ -0,0 +1,26 @@
#pragma once
#include <string>
#include "PlayerMacros.h"
PLAYER_NS_BEGIN
class DeviceEx
{
public:
static DeviceEx *getInstance();
std::string getCurrentUILangName();
std::string getUserGUID();
private:
DeviceEx();
void init();
void makeUILangName();
std::string makeUserGUID();
std::string _uiLangName;
std::string _userGUID;
};
PLAYER_NS_END

View File

@ -0,0 +1,37 @@
#ifndef __PLAYER_EDITBOX_SERVICE_PROTOCOL_H_
#define __PLAYER_EDITBOX_SERVICE_PROTOCOL_H_
#include <string>
#include "cocos2d.h"
#include "PlayerMacros.h"
#include "PlayerServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerEditBoxServiceProtocol : public PlayerServiceProtocol
{
public:
static const int FORMAT_NONE = 0;
static const int FORMAT_NUMBER = 1;
virtual void showSingleLineEditBox(const cocos2d::Rect &rect) = 0;
virtual void showMultiLineEditBox(const cocos2d::Rect &rect) = 0;
virtual void hide() = 0;
virtual void setText(const std::string &text) = 0;
virtual void setFont(const std::string &name, int size) = 0;
virtual void setFontColor(const cocos2d::Color3B &color) = 0;
virtual void setFormator(int formator) = 0;
void registerHandler(int handler) { _handler = handler; }
int getHandler() { return _handler; }
protected:
int _handler;
};
PLAYER_NS_END
#endif // __PLAYER_EDITBOX_SERVICE_PROTOCOL_H_

View File

@ -0,0 +1,33 @@
#ifndef __PLAYER_FILE_DIALOG_SERVICE_PROTOCOL_H_
#define __PLAYER_FILE_DIALOG_SERVICE_PROTOCOL_H_
#include <string>
#include <vector>
#include "PlayerMacros.h"
#include "PlayerServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerFileDialogServiceProtocol : public PlayerServiceProtocol
{
public:
/**
* extensions = "Lua Script File|*.lua;JSON File|*.json";
*/
virtual std::string openFile(const std::string &title,
const std::string &directory,
const std::string &extensions) const = 0;
virtual std::vector<std::string> openMultiple(const std::string &title,
const std::string &directory,
const std::string &extensions) const = 0;
virtual std::string saveFile(const std::string &title,
const std::string &path) const = 0;
virtual std::string openDirectory(const std::string &title,
const std::string &directory) const = 0;
};
PLAYER_NS_END
#endif // __PLAYER_FILE_DIALOG_SERVICE_PROTOCOL_H_

View File

@ -0,0 +1,9 @@
#ifndef __PLAYER_MACROS_H_
#define __PLAYER_MACROS_H_
#define PLAYER_NS_BEGIN namespace player {
#define PLAYER_NS_END }
#define USING_PLAYER_NS using namespace player;
#endif // __PLAYER_MACROS_H_

View File

@ -0,0 +1,53 @@
#include "PlayerMenuServiceProtocol.h"
PLAYER_NS_BEGIN
PlayerMenuItem::PlayerMenuItem()
: _order(0)
, _isGroup(false)
, _isEnabled(true)
, _isChecked(false)
{
}
PlayerMenuItem::~PlayerMenuItem()
{
}
std::string PlayerMenuItem::getMenuId() const
{
return _menuId;
}
std::string PlayerMenuItem::getTitle() const
{
return _title;
}
int PlayerMenuItem::getOrder() const
{
return _order;
}
bool PlayerMenuItem::isGroup() const
{
return _isGroup;
}
bool PlayerMenuItem::isEnabled() const
{
return _isEnabled;
}
bool PlayerMenuItem::isChecked() const
{
return _isChecked;
}
std::string PlayerMenuItem::getShortcut() const
{
return _shortcut;
}
PLAYER_NS_END

View File

@ -0,0 +1,66 @@
#ifndef __PLAYER_MENU_SERVICE_PROTOCOL_H
#define __PLAYER_MENU_SERVICE_PROTOCOL_H
#include <string>
#include "cocos2d.h"
#include "PlayerMacros.h"
#include "PlayerServiceProtocol.h"
PLAYER_NS_BEGIN
#define kPlayerSuperModifyKey "super"
#define kPlayerShiftModifyKey "shift"
#define kPlayerCtrlModifyKey "ctrl"
#define kPlayerAltModifyKey "alt"
class PlayerMenuItem : public cocos2d::Ref
{
public:
virtual ~PlayerMenuItem();
std::string getMenuId() const;
std::string getTitle() const;
int getOrder() const;
bool isGroup() const;
bool isEnabled() const;
bool isChecked() const;
std::string getShortcut() const;
virtual void setTitle(const std::string &title) = 0;
virtual void setEnabled(bool enabled) = 0;
virtual void setChecked(bool checked) = 0;
virtual void setShortcut(const std::string &shortcut) = 0;
protected:
PlayerMenuItem();
std::string _menuId;
std::string _title;
int _order;
bool _isGroup;
bool _isEnabled;
bool _isChecked; // ignored when isGroup = true
std::string _shortcut; // ignored when isGroup = true
};
class PlayerMenuServiceProtocol : public PlayerServiceProtocol
{
public:
static const int MAX_ORDER = 9999;
virtual PlayerMenuItem *addItem(const std::string &menuId,
const std::string &title,
const std::string &parentId,
int order = MAX_ORDER) = 0;
virtual PlayerMenuItem *addItem(const std::string &menuId,
const std::string &title) = 0;
virtual PlayerMenuItem *getItem(const std::string &menuId) = 0;
virtual bool removeItem(const std::string &menuId) = 0;
virtual void setMenuBarEnabled(bool enabled) = 0;
};
PLAYER_NS_END
#endif // __PLAYER_MENU_SERVICE_PROTOCOL_H

View File

@ -0,0 +1,35 @@
#ifndef __PLAYER_MESSAGEBOX_SERVICE_PROTOCOL_H
#define __PLAYER_MESSAGEBOX_SERVICE_PROTOCOL_H
#include <string>
#include "PlayerMacros.h"
#include "PlayerServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerMessageBoxServiceProtocol : public PlayerServiceProtocol
{
public:
static const int BUTTONS_OK = 0;
static const int BUTTONS_OK_CANCEL = 1;
static const int BUTTONS_YES_NO = 2;
static const int BUTTONS_YES_NO_CANCEL = 3;
static const int BUTTON_OK = 0;
static const int BUTTON_CANCEL = 1;
static const int BUTTON_YES = 2;
static const int BUTTON_NO = 3;
// Show a message box, return index of user clicked button
//
// @return int first button index is 0
virtual int showMessageBox(const std::string &title,
const std::string &message,
int buttonsType = BUTTONS_OK) = 0;
};
PLAYER_NS_END
#endif // __PLAYER_MESSAGEBOX_SERVICE_PROTOCOL_H

View File

@ -0,0 +1,42 @@
#include "PlayerProtocol.h"
#include "base/ccMacros.h"
PLAYER_NS_BEGIN
USING_NS_CC;
PlayerProtocol *PlayerProtocol::_instance = nullptr;
PlayerProtocol::PlayerProtocol()
{
CCASSERT(_instance == nullptr, "CAN NOT CREATE MORE PLAYER INSTANCE");
_instance = this;
}
PlayerProtocol::~PlayerProtocol()
{
_instance = nullptr;
}
PlayerProtocol *PlayerProtocol::getInstance()
{
return _instance;
}
void PlayerProtocol::purgeInstance()
{
if (_instance) delete _instance;
}
void PlayerProtocol::setPlayerSettings(const PlayerSettings &settings)
{
_settings = settings;
}
PlayerSettings PlayerProtocol::getPlayerSettings() const
{
return _settings;
}
PLAYER_NS_END

View File

@ -0,0 +1,58 @@
#ifndef __PLAYER_PROTOCOL_H_
#define __PLAYER_PROTOCOL_H_
#include "PlayerMacros.h"
#include "PlayerSettings.h"
#include "PlayerFileDialogServiceProtocol.h"
#include "PlayerMessageBoxServiceProtocol.h"
#include "PlayerMenuServiceProtocol.h"
#include "PlayerEditBoxServiceProtocol.h"
#include "PlayerTaskServiceProtocol.h"
#include "ProjectConfig/ProjectConfig.h"
PLAYER_NS_BEGIN
class PlayerProtocol
{
public:
virtual ~PlayerProtocol();
static PlayerProtocol *getInstance();
static void purgeInstance();
void setPlayerSettings(const PlayerSettings &settings);
PlayerSettings getPlayerSettings() const;
virtual PlayerFileDialogServiceProtocol *getFileDialogService() = 0; // implemented in platform related source files
virtual PlayerMessageBoxServiceProtocol *getMessageBoxService() = 0;
virtual PlayerMenuServiceProtocol *getMenuService() = 0;
virtual PlayerEditBoxServiceProtocol *getEditBoxService() = 0;
virtual PlayerTaskServiceProtocol *getTaskService() = 0;
// player function
virtual void quit() = 0;
virtual void relaunch() = 0;
virtual void openNewPlayer() = 0;
virtual void openNewPlayerWithProjectConfig(const ProjectConfig &config) = 0;
virtual void openProjectWithProjectConfig(const ProjectConfig &config) = 0;
// window info
virtual int getPositionX() = 0;
virtual int getPositionY() = 0;
protected:
PlayerProtocol(); // avoid create instance from outside
PlayerSettings _settings;
private:
static PlayerProtocol *_instance;
};
PLAYER_NS_END
#endif // __PLAYER_PROTOCOL_H_

View File

@ -0,0 +1,6 @@
#include "PlayerServiceProtocol.h"
PLAYER_NS_BEGIN
PLAYER_NS_END

View File

@ -0,0 +1,17 @@
#ifndef __PLAYER_SERVICE_PROTOCOL_H_
#define __PLAYER_SERVICE_PROTOCOL_H_
#include "PlayerMacros.h"
PLAYER_NS_BEGIN
class PlayerServiceProtocol
{
public:
virtual ~PlayerServiceProtocol() {};
};
PLAYER_NS_END
#endif // __PLAYER_SERVICE_PROTOCOL_H_

View File

@ -0,0 +1,2 @@
#include "PlayerSettings.h"

View File

@ -0,0 +1,25 @@
#ifndef __PLAYER_SETTINGS_H_
#define __PLAYER_SETTINGS_H_
#include "PlayerMacros.h"
PLAYER_NS_BEGIN
class PlayerSettings
{
public:
PlayerSettings()
: openLastProject(false)
, offsetX(0)
, offsetY(0)
{}
bool openLastProject;
int offsetX;
int offsetY;
};
PLAYER_NS_END
#endif // __PLAYER_SETTINGS_H_

View File

@ -0,0 +1,68 @@
#include "PlayerTaskServiceProtocol.h"
PLAYER_NS_BEGIN
std::string PlayerTask::getName() const
{
return _name;
}
std::string PlayerTask::getExecutePath() const
{
return _executePath;
}
std::string PlayerTask::getCommandLineArguments() const
{
return _commandLineArguments;
}
std::string PlayerTask::getOutput() const
{
return _output;
}
int PlayerTask::getState() const
{
return _state;
}
bool PlayerTask::isIdle() const
{
return _state == STATE_IDLE;
}
bool PlayerTask::isRunning() const
{
return _state == STATE_RUNNING;
}
bool PlayerTask::isCompleted() const
{
return _state == STATE_COMPLETED;
}
float PlayerTask::getLifetime() const
{
return _lifetime;
}
int PlayerTask::getResultCode() const
{
return _resultCode;
}
PlayerTask::PlayerTask(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments)
: _name(name)
, _executePath(executePath)
, _commandLineArguments(commandLineArguments)
, _state(STATE_IDLE)
, _lifetime(0)
, _resultCode(0)
{
}
PLAYER_NS_END

View File

@ -0,0 +1,63 @@
#ifndef __PLAYER_TASK_SERVICE_PROTOCOL_H
#define __PLAYER_TASK_SERVICE_PROTOCOL_H
#include <string>
#include "cocos2d.h"
#include "PlayerMacros.h"
#include "PlayerServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerTask : public cocos2d::Ref
{
public:
static const int STATE_IDLE = 0;
static const int STATE_RUNNING = 1;
static const int STATE_COMPLETED = 2;
virtual ~PlayerTask() {};
std::string getName() const;
std::string getExecutePath() const;
std::string getCommandLineArguments() const;
std::string getOutput() const;
int getState() const;
bool isIdle() const;
bool isRunning() const;
bool isCompleted() const;
float getLifetime() const;
int getResultCode() const;
virtual bool run() = 0;
virtual void stop() = 0;
virtual void runInTerminal() = 0;
protected:
PlayerTask(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments);
std::string _name;
std::string _executePath;
std::string _commandLineArguments;
std::string _output;
float _lifetime;
int _state;
int _resultCode;
};
class PlayerTaskServiceProtocol : public PlayerServiceProtocol
{
public:
virtual PlayerTask *createTask(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments) = 0;
virtual PlayerTask *getTask(const std::string &name) = 0;
virtual void removeTask(const std::string &name) = 0;
};
PLAYER_NS_END
#endif // __PLAYER_TASK_SERVICE_PROTOCOL_H

View File

@ -0,0 +1,2 @@
#include "PlayerUtils.h"

View File

@ -0,0 +1,36 @@
#ifndef __PLAYER_UTILS_H_
#define __PLAYER_UTILS_H_
#include "PlayerMacros.h"
#include <string>
#include <vector>
using namespace std;
PLAYER_NS_BEGIN
template<class T>
vector<T> splitString(T str, T pattern)
{
vector<T> result;
str += pattern;
size_t size = str.size();
for (size_t i = 0; i < size; i++)
{
size_t pos = str.find(pattern, i);
if (pos < size)
{
T s = str.substr(i, pos - i);
result.push_back(s);
i = pos + pattern.size() - 1;
}
}
return result;
};
PLAYER_NS_END
#endif // __PLAYER_UTILS_H_

View File

@ -33,6 +33,9 @@ LOCAL_SRC_FILES := \
../../Classes/VisibleRect.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/ConfigParser.cpp \
../../Classes/ProjectConfig/ProjectConfig.cpp \
../../Classes/ProjectConfig/SimulatorConfig.cpp \
../../Classes/network/CCHTTPRequest.cpp \
hellolua/Runtime_android.cpp \
hellolua/main.cpp

View File

@ -77,6 +77,32 @@
50D7C97017EBBEEC005D0B91 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50D7C96F17EBBEEC005D0B91 /* IOKit.framework */; };
521A8E7019F0C3D200D177D7 /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 521A8E6E19F0C3D200D177D7 /* Default-667h@2x.png */; };
521A8E7119F0C3D200D177D7 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 521A8E6F19F0C3D200D177D7 /* Default-736h@3x.png */; };
9FFC06F91A4A733B00AED399 /* ConsoleWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9FFC06EA1A4A733B00AED399 /* ConsoleWindow.xib */; };
9FFC06FA1A4A733B00AED399 /* ConsoleWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC06EC1A4A733B00AED399 /* ConsoleWindowController.m */; };
9FFC06FB1A4A733B00AED399 /* PlayerEditBoxServiceMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC06EE1A4A733B00AED399 /* PlayerEditBoxServiceMac.mm */; };
9FFC06FC1A4A733B00AED399 /* PlayerFileDialogServiceMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC06F01A4A733B00AED399 /* PlayerFileDialogServiceMac.mm */; };
9FFC06FD1A4A733B00AED399 /* PlayerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC06F21A4A733B00AED399 /* PlayerMac.mm */; };
9FFC06FE1A4A733B00AED399 /* PlayerMenuServiceMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC06F41A4A733B00AED399 /* PlayerMenuServiceMac.mm */; };
9FFC06FF1A4A733B00AED399 /* PlayerMessageBoxServiceMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC06F61A4A733B00AED399 /* PlayerMessageBoxServiceMac.mm */; };
9FFC07001A4A733B00AED399 /* PlayerTaskServiceMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC06F81A4A733B00AED399 /* PlayerTaskServiceMac.mm */; };
9FFC07041A4A737300AED399 /* OpenUDIDMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07031A4A737300AED399 /* OpenUDIDMac.m */; };
9FFC07261A4A739200AED399 /* lang in Resources */ = {isa = PBXBuildFile; fileRef = 9FFC07061A4A739200AED399 /* lang */; };
9FFC07271A4A739200AED399 /* CCHTTPRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07081A4A739200AED399 /* CCHTTPRequest.cpp */; };
9FFC07281A4A739200AED399 /* ProjectConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC070C1A4A739200AED399 /* ProjectConfig.cpp */; };
9FFC07291A4A739200AED399 /* SimulatorConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC070E1A4A739200AED399 /* SimulatorConfig.cpp */; };
9FFC072A1A4A739200AED399 /* AppEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07111A4A739200AED399 /* AppEvent.cpp */; };
9FFC072B1A4A739200AED399 /* AppLang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07131A4A739200AED399 /* AppLang.cpp */; };
9FFC072C1A4A739200AED399 /* PlayerMenuServiceProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07191A4A739200AED399 /* PlayerMenuServiceProtocol.cpp */; };
9FFC072D1A4A739200AED399 /* PlayerProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC071C1A4A739200AED399 /* PlayerProtocol.cpp */; };
9FFC072E1A4A739200AED399 /* PlayerServiceProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC071E1A4A739200AED399 /* PlayerServiceProtocol.cpp */; };
9FFC072F1A4A739200AED399 /* PlayerSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07201A4A739200AED399 /* PlayerSettings.cpp */; };
9FFC07301A4A739200AED399 /* PlayerTaskServiceProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07221A4A739200AED399 /* PlayerTaskServiceProtocol.cpp */; };
9FFC07311A4A739200AED399 /* PlayerUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07241A4A739200AED399 /* PlayerUtils.cpp */; };
9FFC07331A4A73F700AED399 /* DeviceEx-mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07321A4A73F700AED399 /* DeviceEx-mac.mm */; };
9FFC07361A4A764100AED399 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9FFC07341A4A764100AED399 /* MainMenu.xib */; };
9FFC073F1A4AA91100AED399 /* ProjectConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC070C1A4A739200AED399 /* ProjectConfig.cpp */; };
9FFC07401A4AA91B00AED399 /* CCHTTPRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC07081A4A739200AED399 /* CCHTTPRequest.cpp */; };
9FFC07411A4AAB2F00AED399 /* SimulatorConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9FFC070E1A4A739200AED399 /* SimulatorConfig.cpp */; };
AB6CB6F21A1F275E009C2562 /* ConnectWaitLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB6CB6EC1A1F275E009C2562 /* ConnectWaitLayer.cpp */; };
AB6CB6F31A1F275E009C2562 /* ConnectWaitLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB6CB6EC1A1F275E009C2562 /* ConnectWaitLayer.cpp */; };
AB6CB6F41A1F275E009C2562 /* ConsoleCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB6CB6EE1A1F275E009C2562 /* ConsoleCommand.cpp */; };
@ -117,7 +143,6 @@
F293B3D915EB7BE500256477 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F293B3D815EB7BE500256477 /* Foundation.framework */; };
F293B3DB15EB7BE500256477 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F293B3DA15EB7BE500256477 /* CoreGraphics.framework */; };
F293BB9C15EB831F00256477 /* AppDelegate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F293BB7E15EB831F00256477 /* AppDelegate.cpp */; };
F405C6C919ED14AA005AD31C /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F405C6CB19ED14AA005AD31C /* MainMenu.xib */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -262,6 +287,57 @@
50D7C96F17EBBEEC005D0B91 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
521A8E6E19F0C3D200D177D7 /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = "<group>"; };
521A8E6F19F0C3D200D177D7 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = "<group>"; };
9FFC06EA1A4A733B00AED399 /* ConsoleWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConsoleWindow.xib; sourceTree = "<group>"; };
9FFC06EB1A4A733B00AED399 /* ConsoleWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleWindowController.h; sourceTree = "<group>"; };
9FFC06EC1A4A733B00AED399 /* ConsoleWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConsoleWindowController.m; sourceTree = "<group>"; };
9FFC06ED1A4A733B00AED399 /* PlayerEditBoxServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerEditBoxServiceMac.h; sourceTree = "<group>"; };
9FFC06EE1A4A733B00AED399 /* PlayerEditBoxServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerEditBoxServiceMac.mm; sourceTree = "<group>"; };
9FFC06EF1A4A733B00AED399 /* PlayerFileDialogServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerFileDialogServiceMac.h; sourceTree = "<group>"; };
9FFC06F01A4A733B00AED399 /* PlayerFileDialogServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerFileDialogServiceMac.mm; sourceTree = "<group>"; };
9FFC06F11A4A733B00AED399 /* PlayerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMac.h; sourceTree = "<group>"; };
9FFC06F21A4A733B00AED399 /* PlayerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerMac.mm; sourceTree = "<group>"; };
9FFC06F31A4A733B00AED399 /* PlayerMenuServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMenuServiceMac.h; sourceTree = "<group>"; };
9FFC06F41A4A733B00AED399 /* PlayerMenuServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerMenuServiceMac.mm; sourceTree = "<group>"; };
9FFC06F51A4A733B00AED399 /* PlayerMessageBoxServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMessageBoxServiceMac.h; sourceTree = "<group>"; };
9FFC06F61A4A733B00AED399 /* PlayerMessageBoxServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerMessageBoxServiceMac.mm; sourceTree = "<group>"; };
9FFC06F71A4A733B00AED399 /* PlayerTaskServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerTaskServiceMac.h; sourceTree = "<group>"; };
9FFC06F81A4A733B00AED399 /* PlayerTaskServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerTaskServiceMac.mm; sourceTree = "<group>"; };
9FFC07021A4A737300AED399 /* OpenUDIDMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenUDIDMac.h; sourceTree = "<group>"; };
9FFC07031A4A737300AED399 /* OpenUDIDMac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OpenUDIDMac.m; sourceTree = "<group>"; };
9FFC07051A4A739200AED399 /* cocos2dx_extra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cocos2dx_extra.h; path = ../Classes/cocos2dx_extra.h; sourceTree = "<group>"; };
9FFC07061A4A739200AED399 /* lang */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = lang; path = ../Classes/lang; sourceTree = "<group>"; };
9FFC07081A4A739200AED399 /* CCHTTPRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCHTTPRequest.cpp; sourceTree = "<group>"; };
9FFC07091A4A739200AED399 /* CCHTTPRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCHTTPRequest.h; sourceTree = "<group>"; };
9FFC070A1A4A739200AED399 /* CCHTTPRequestDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCHTTPRequestDelegate.h; sourceTree = "<group>"; };
9FFC070C1A4A739200AED399 /* ProjectConfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectConfig.cpp; sourceTree = "<group>"; };
9FFC070D1A4A739200AED399 /* ProjectConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectConfig.h; sourceTree = "<group>"; };
9FFC070E1A4A739200AED399 /* SimulatorConfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimulatorConfig.cpp; sourceTree = "<group>"; };
9FFC070F1A4A739200AED399 /* SimulatorConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimulatorConfig.h; sourceTree = "<group>"; };
9FFC07111A4A739200AED399 /* AppEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppEvent.cpp; sourceTree = "<group>"; };
9FFC07121A4A739200AED399 /* AppEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppEvent.h; sourceTree = "<group>"; };
9FFC07131A4A739200AED399 /* AppLang.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppLang.cpp; sourceTree = "<group>"; };
9FFC07141A4A739200AED399 /* AppLang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppLang.h; sourceTree = "<group>"; };
9FFC07151A4A739200AED399 /* DeviceEx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceEx.h; sourceTree = "<group>"; };
9FFC07161A4A739200AED399 /* PlayerEditBoxServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerEditBoxServiceProtocol.h; sourceTree = "<group>"; };
9FFC07171A4A739200AED399 /* PlayerFileDialogServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerFileDialogServiceProtocol.h; sourceTree = "<group>"; };
9FFC07181A4A739200AED399 /* PlayerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMacros.h; sourceTree = "<group>"; };
9FFC07191A4A739200AED399 /* PlayerMenuServiceProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerMenuServiceProtocol.cpp; sourceTree = "<group>"; };
9FFC071A1A4A739200AED399 /* PlayerMenuServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMenuServiceProtocol.h; sourceTree = "<group>"; };
9FFC071B1A4A739200AED399 /* PlayerMessageBoxServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMessageBoxServiceProtocol.h; sourceTree = "<group>"; };
9FFC071C1A4A739200AED399 /* PlayerProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerProtocol.cpp; sourceTree = "<group>"; };
9FFC071D1A4A739200AED399 /* PlayerProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerProtocol.h; sourceTree = "<group>"; };
9FFC071E1A4A739200AED399 /* PlayerServiceProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerServiceProtocol.cpp; sourceTree = "<group>"; };
9FFC071F1A4A739200AED399 /* PlayerServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerServiceProtocol.h; sourceTree = "<group>"; };
9FFC07201A4A739200AED399 /* PlayerSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerSettings.cpp; sourceTree = "<group>"; };
9FFC07211A4A739200AED399 /* PlayerSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerSettings.h; sourceTree = "<group>"; };
9FFC07221A4A739200AED399 /* PlayerTaskServiceProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerTaskServiceProtocol.cpp; sourceTree = "<group>"; };
9FFC07231A4A739200AED399 /* PlayerTaskServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerTaskServiceProtocol.h; sourceTree = "<group>"; };
9FFC07241A4A739200AED399 /* PlayerUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerUtils.cpp; sourceTree = "<group>"; };
9FFC07251A4A739200AED399 /* PlayerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerUtils.h; sourceTree = "<group>"; };
9FFC07321A4A73F700AED399 /* DeviceEx-mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DeviceEx-mac.mm"; sourceTree = "<group>"; };
9FFC07351A4A764100AED399 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
9FFC07371A4A765100AED399 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.xib"; sourceTree = "<group>"; };
9FFC07381A4A902500AED399 /* CodeIDESupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeIDESupport.h; path = ../Classes/CodeIDESupport.h; sourceTree = "<group>"; };
AB6CB6EC1A1F275E009C2562 /* ConnectWaitLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConnectWaitLayer.cpp; sourceTree = "<group>"; };
AB6CB6ED1A1F275E009C2562 /* ConnectWaitLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectWaitLayer.h; sourceTree = "<group>"; };
AB6CB6EE1A1F275E009C2562 /* ConsoleCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleCommand.cpp; sourceTree = "<group>"; };
@ -300,7 +376,6 @@
F293B3DA15EB7BE500256477 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
F293BB7E15EB831F00256477 /* AppDelegate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AppDelegate.cpp; path = ../Classes/AppDelegate.cpp; sourceTree = "<group>"; };
F293BB7F15EB831F00256477 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../Classes/AppDelegate.h; sourceTree = "<group>"; };
F405C6CA19ED14AA005AD31C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -456,9 +531,10 @@
5023817117EBBE3400990C9B /* mac */ = {
isa = PBXGroup;
children = (
9FFC06E91A4A733B00AED399 /* service */,
5023817217EBBE3400990C9B /* Icon.icns */,
9FFC07341A4A764100AED399 /* MainMenu.xib */,
C07828F418B4D72E00BD2287 /* main.m */,
F405C6CB19ED14AA005AD31C /* MainMenu.xib */,
C07828F618B4D72E00BD2287 /* SimulatorApp.h */,
C07828F718B4D72E00BD2287 /* SimulatorApp.mm */,
5023817317EBBE3400990C9B /* Info.plist */,
@ -487,6 +563,91 @@
name = Icons;
sourceTree = "<group>";
};
9FFC06E91A4A733B00AED399 /* service */ = {
isa = PBXGroup;
children = (
9FFC07011A4A737300AED399 /* openudid */,
9FFC06EA1A4A733B00AED399 /* ConsoleWindow.xib */,
9FFC06EB1A4A733B00AED399 /* ConsoleWindowController.h */,
9FFC06EC1A4A733B00AED399 /* ConsoleWindowController.m */,
9FFC07321A4A73F700AED399 /* DeviceEx-mac.mm */,
9FFC06ED1A4A733B00AED399 /* PlayerEditBoxServiceMac.h */,
9FFC06EE1A4A733B00AED399 /* PlayerEditBoxServiceMac.mm */,
9FFC06EF1A4A733B00AED399 /* PlayerFileDialogServiceMac.h */,
9FFC06F01A4A733B00AED399 /* PlayerFileDialogServiceMac.mm */,
9FFC06F11A4A733B00AED399 /* PlayerMac.h */,
9FFC06F21A4A733B00AED399 /* PlayerMac.mm */,
9FFC06F31A4A733B00AED399 /* PlayerMenuServiceMac.h */,
9FFC06F41A4A733B00AED399 /* PlayerMenuServiceMac.mm */,
9FFC06F51A4A733B00AED399 /* PlayerMessageBoxServiceMac.h */,
9FFC06F61A4A733B00AED399 /* PlayerMessageBoxServiceMac.mm */,
9FFC06F71A4A733B00AED399 /* PlayerTaskServiceMac.h */,
9FFC06F81A4A733B00AED399 /* PlayerTaskServiceMac.mm */,
);
path = service;
sourceTree = "<group>";
};
9FFC07011A4A737300AED399 /* openudid */ = {
isa = PBXGroup;
children = (
9FFC07021A4A737300AED399 /* OpenUDIDMac.h */,
9FFC07031A4A737300AED399 /* OpenUDIDMac.m */,
);
path = openudid;
sourceTree = "<group>";
};
9FFC07071A4A739200AED399 /* network */ = {
isa = PBXGroup;
children = (
9FFC07081A4A739200AED399 /* CCHTTPRequest.cpp */,
9FFC07091A4A739200AED399 /* CCHTTPRequest.h */,
9FFC070A1A4A739200AED399 /* CCHTTPRequestDelegate.h */,
);
name = network;
path = ../Classes/network;
sourceTree = "<group>";
};
9FFC070B1A4A739200AED399 /* ProjectConfig */ = {
isa = PBXGroup;
children = (
9FFC070C1A4A739200AED399 /* ProjectConfig.cpp */,
9FFC070D1A4A739200AED399 /* ProjectConfig.h */,
9FFC070E1A4A739200AED399 /* SimulatorConfig.cpp */,
9FFC070F1A4A739200AED399 /* SimulatorConfig.h */,
);
name = ProjectConfig;
path = ../Classes/ProjectConfig;
sourceTree = "<group>";
};
9FFC07101A4A739200AED399 /* service */ = {
isa = PBXGroup;
children = (
9FFC07111A4A739200AED399 /* AppEvent.cpp */,
9FFC07121A4A739200AED399 /* AppEvent.h */,
9FFC07131A4A739200AED399 /* AppLang.cpp */,
9FFC07141A4A739200AED399 /* AppLang.h */,
9FFC07151A4A739200AED399 /* DeviceEx.h */,
9FFC07161A4A739200AED399 /* PlayerEditBoxServiceProtocol.h */,
9FFC07171A4A739200AED399 /* PlayerFileDialogServiceProtocol.h */,
9FFC07181A4A739200AED399 /* PlayerMacros.h */,
9FFC07191A4A739200AED399 /* PlayerMenuServiceProtocol.cpp */,
9FFC071A1A4A739200AED399 /* PlayerMenuServiceProtocol.h */,
9FFC071B1A4A739200AED399 /* PlayerMessageBoxServiceProtocol.h */,
9FFC071C1A4A739200AED399 /* PlayerProtocol.cpp */,
9FFC071D1A4A739200AED399 /* PlayerProtocol.h */,
9FFC071E1A4A739200AED399 /* PlayerServiceProtocol.cpp */,
9FFC071F1A4A739200AED399 /* PlayerServiceProtocol.h */,
9FFC07201A4A739200AED399 /* PlayerSettings.cpp */,
9FFC07211A4A739200AED399 /* PlayerSettings.h */,
9FFC07221A4A739200AED399 /* PlayerTaskServiceProtocol.cpp */,
9FFC07231A4A739200AED399 /* PlayerTaskServiceProtocol.h */,
9FFC07241A4A739200AED399 /* PlayerUtils.cpp */,
9FFC07251A4A739200AED399 /* PlayerUtils.h */,
);
name = service;
path = ../Classes/service;
sourceTree = "<group>";
};
C00FD4891938512100C6382D /* runtime */ = {
isa = PBXGroup;
children = (
@ -575,6 +736,12 @@
F293BB7C15EB830F00256477 /* Classes */ = {
isa = PBXGroup;
children = (
9FFC07381A4A902500AED399 /* CodeIDESupport.h */,
9FFC07051A4A739200AED399 /* cocos2dx_extra.h */,
9FFC07061A4A739200AED399 /* lang */,
9FFC07071A4A739200AED399 /* network */,
9FFC070B1A4A739200AED399 /* ProjectConfig */,
9FFC07101A4A739200AED399 /* service */,
15427CE2198F237300DC375D /* lua_module_register.h */,
C00FD4891938512100C6382D /* runtime */,
C033B51A191B337200D06937 /* VisibleRect.cpp */,
@ -660,6 +827,8 @@
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
"zh-Hans",
);
mainGroup = F293B3BD15EB7BE500256477;
productRefGroup = F293B3C915EB7BE500256477 /* Products */;
@ -719,9 +888,11 @@
buildActionMask = 2147483647;
files = (
C03781BA18BF655400FE4F13 /* res in Resources */,
9FFC06F91A4A733B00AED399 /* ConsoleWindow.xib in Resources */,
C03781BC18BF655400FE4F13 /* src in Resources */,
F405C6C919ED14AA005AD31C /* MainMenu.xib in Resources */,
9FFC07261A4A739200AED399 /* lang in Resources */,
5023817617EBBE3400990C9B /* Icon.icns in Resources */,
9FFC07361A4A764100AED399 /* MainMenu.xib in Resources */,
C05D1C131923449100B808A4 /* config.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -779,19 +950,34 @@
files = (
AB6CB6F31A1F275E009C2562 /* ConnectWaitLayer.cpp in Sources */,
C07828FA18B4D72E00BD2287 /* SimulatorApp.mm in Sources */,
9FFC07291A4A739200AED399 /* SimulatorConfig.cpp in Sources */,
5023813317EBBCE400990C9B /* AppDelegate.cpp in Sources */,
9FFC06FE1A4A733B00AED399 /* PlayerMenuServiceMac.mm in Sources */,
9FFC06FA1A4A733B00AED399 /* ConsoleWindowController.m in Sources */,
9FFC06FC1A4A733B00AED399 /* PlayerFileDialogServiceMac.mm in Sources */,
C00FD4971938512100C6382D /* PlayEnable_png.cpp in Sources */,
C00FD4951938512100C6382D /* PlayDisable_png.cpp in Sources */,
9FFC072F1A4A739200AED399 /* PlayerSettings.cpp in Sources */,
AB6CB6F51A1F275E009C2562 /* ConsoleCommand.cpp in Sources */,
C033B51D191B337200D06937 /* VisibleRect.cpp in Sources */,
9FFC06FF1A4A733B00AED399 /* PlayerMessageBoxServiceMac.mm in Sources */,
9FFC06FB1A4A733B00AED399 /* PlayerEditBoxServiceMac.mm in Sources */,
9FFC07311A4A739200AED399 /* PlayerUtils.cpp in Sources */,
C00FD49D1938512100C6382D /* Shine_png.cpp in Sources */,
3EB515691952865D006966AA /* common.cc in Sources */,
15AA9649199B6D4600725633 /* lua_debugger.c in Sources */,
9FFC072A1A4A739200AED399 /* AppEvent.cpp in Sources */,
9FFC07041A4A737300AED399 /* OpenUDIDMac.m in Sources */,
3EB515651952865D006966AA /* repeated_field.cc in Sources */,
9FFC072B1A4A739200AED399 /* AppLang.cpp in Sources */,
3EB5156B1952865D006966AA /* once.cc in Sources */,
9FFC07301A4A739200AED399 /* PlayerTaskServiceProtocol.cpp in Sources */,
3EB5155D1952865D006966AA /* coded_stream.cc in Sources */,
C00FD4991938512100C6382D /* Portrait_png.cpp in Sources */,
C06C3797191A1D1E00617BED /* ConfigParser.cpp in Sources */,
9FFC07271A4A739200AED399 /* CCHTTPRequest.cpp in Sources */,
9FFC072E1A4A739200AED399 /* PlayerServiceProtocol.cpp in Sources */,
9FFC07281A4A739200AED399 /* ProjectConfig.cpp in Sources */,
3EB5156D1952865D006966AA /* stringprintf.cc in Sources */,
C07828F818B4D72E00BD2287 /* main.m in Sources */,
3EB515611952865D006966AA /* zero_copy_stream_impl_lite.cc in Sources */,
@ -800,8 +986,13 @@
C00FD49B1938512100C6382D /* Runtime.cpp in Sources */,
3EB515591952865D006966AA /* extension_set.cc in Sources */,
3EB5155B1952865D006966AA /* generated_message_util.cc in Sources */,
9FFC072D1A4A739200AED399 /* PlayerProtocol.cpp in Sources */,
C0619CD81896894800872C26 /* Runtime_ios-mac.mm in Sources */,
9FFC072C1A4A739200AED399 /* PlayerMenuServiceProtocol.cpp in Sources */,
9FFC07001A4A733B00AED399 /* PlayerTaskServiceMac.mm in Sources */,
9FFC06FD1A4A733B00AED399 /* PlayerMac.mm in Sources */,
3EB5152D19528284006966AA /* Protos.pb.cc in Sources */,
9FFC07331A4A73F700AED399 /* DeviceEx-mac.mm in Sources */,
AB6CB6F71A1F275E009C2562 /* FileServer.cpp in Sources */,
C00FD4931938512100C6382D /* Landscape_png.cpp in Sources */,
3EB5155F1952865D006966AA /* zero_copy_stream.cc in Sources */,
@ -817,6 +1008,7 @@
3EB5156A1952865D006966AA /* once.cc in Sources */,
C00FD4981938512100C6382D /* Portrait_png.cpp in Sources */,
5023812517EBBCAC00990C9B /* RootViewController.mm in Sources */,
9FFC073F1A4AA91100AED399 /* ProjectConfig.cpp in Sources */,
C00FD4921938512100C6382D /* Landscape_png.cpp in Sources */,
F293BB9C15EB831F00256477 /* AppDelegate.cpp in Sources */,
C00FD49A1938512100C6382D /* Runtime.cpp in Sources */,
@ -829,6 +1021,7 @@
3EB515641952865D006966AA /* repeated_field.cc in Sources */,
C00FD4941938512100C6382D /* PlayDisable_png.cpp in Sources */,
C00FD49C1938512100C6382D /* Shine_png.cpp in Sources */,
9FFC07401A4AA91B00AED399 /* CCHTTPRequest.cpp in Sources */,
3EB5156E1952865D006966AA /* wire_format_lite.cc in Sources */,
AB6CB6F21A1F275E009C2562 /* ConnectWaitLayer.cpp in Sources */,
3EB515581952865D006966AA /* extension_set.cc in Sources */,
@ -841,6 +1034,7 @@
3EB5155E1952865D006966AA /* zero_copy_stream.cc in Sources */,
3EB5155C1952865D006966AA /* coded_stream.cc in Sources */,
C0619CD71896894800872C26 /* Runtime_ios-mac.mm in Sources */,
9FFC07411A4AAB2F00AED399 /* SimulatorConfig.cpp in Sources */,
5023811817EBBCAC00990C9B /* AppController.mm in Sources */,
AB6CB6F41A1F275E009C2562 /* ConsoleCommand.cpp in Sources */,
);
@ -872,10 +1066,11 @@
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
F405C6CB19ED14AA005AD31C /* MainMenu.xib */ = {
9FFC07341A4A764100AED399 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
F405C6CA19ED14AA005AD31C /* en */,
9FFC07351A4A764100AED399 /* Base */,
9FFC07371A4A765100AED399 /* zh-Hans */,
);
name = MainMenu.xib;
sourceTree = "<group>";
@ -899,7 +1094,11 @@
CC_TARGET_OS_MAC,
"$(inherited)",
);
HEADER_SEARCH_PATHS = "$(SRCROOT)/../Classes/protobuf-lite";
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/../Classes/protobuf-lite",
"$(SRCROOT)/../Classes/service",
"$(SRCROOT)/../Classes",
);
INFOPLIST_FILE = mac/Info.plist;
LIBRARY_SEARCH_PATHS = "";
MACOSX_DEPLOYMENT_TARGET = 10.8;
@ -928,7 +1127,11 @@
CC_TARGET_OS_MAC,
"$(inherited)",
);
HEADER_SEARCH_PATHS = "$(SRCROOT)/../Classes/protobuf-lite";
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/../Classes/protobuf-lite",
"$(SRCROOT)/../Classes/service",
"$(SRCROOT)/../Classes",
);
INFOPLIST_FILE = mac/Info.plist;
LIBRARY_SEARCH_PATHS = "";
MACOSX_DEPLOYMENT_TARGET = 10.8;
@ -1004,13 +1207,17 @@
CC_TARGET_OS_IPHONE,
"$(inherited)",
);
HEADER_SEARCH_PATHS = "$(SRCROOT)/../Classes/protobuf-lite";
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/../Classes/protobuf-lite",
"$(SRCROOT)/../Classes/service",
"$(SRCROOT)/../Classes",
);
INFOPLIST_FILE = ios/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
LIBRARY_SEARCH_PATHS = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../../cocos2d-x/cocos/platform/ios";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../../cocos2d-x/cocos/platform/ios $(SRCROOT)/../../cocos2d-x/external/curl/include/ios";
VALID_ARCHS = "arm64 armv7";
};
name = Debug;
@ -1027,13 +1234,17 @@
CC_TARGET_OS_IPHONE,
"$(inherited)",
);
HEADER_SEARCH_PATHS = "$(SRCROOT)/../Classes/protobuf-lite";
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/../Classes/protobuf-lite",
"$(SRCROOT)/../Classes/service",
"$(SRCROOT)/../Classes",
);
INFOPLIST_FILE = ios/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
LIBRARY_SEARCH_PATHS = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../../cocos2d-x/cocos/platform/ios";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../../cocos2d-x/cocos/platform/ios $(SRCROOT)/../../cocos2d-x/external/curl/include/ios";
VALID_ARCHS = "arm64 armv7";
};
name = Release;

View File

@ -5,6 +5,9 @@
#include <string>
#include <vector>
#include "ConfigParser.h"
using namespace std;
string getIPAddress()
@ -13,6 +16,13 @@ string getIPAddress()
struct ifaddrs * addrs;
const struct ifaddrs * cursor;
// customized by user
auto &bindAddress = ConfigParser::getInstance()->getBindAddress();
if (bindAddress.length() > 0)
{
return bindAddress;
}
success = getifaddrs(&addrs) == 0;
if (success) {
cursor = addrs;

View File

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6254"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AppController">
<connections>
<outlet property="delegate" destination="536" id="537"/>
<outlet property="menu" destination="29" id="650"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<menu title="AMainMenu" systemMenu="main" id="29">
<items>
<menuItem title="Simulator" id="56">
<menu key="submenu" title="Simulator" systemMenu="apple" id="57">
<items>
<menuItem title="About simulator" id="58">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="236">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
<menuItem isSeparatorItem="YES" id="143">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Services" id="131">
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="144">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Hide simulator" keyEquivalent="h" id="134">
<connections>
<action selector="hide:" target="-1" id="367"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="145">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="368"/>
</connections>
</menuItem>
<menuItem title="Show All" id="150">
<connections>
<action selector="unhideAllApplications:" target="-1" id="370"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="149">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit simulator" keyEquivalent="q" id="136">
<connections>
<action selector="onFileClose:" target="-1" id="UyZ-bV-2zL"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="Sqe-GR-erP">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="k0V-hR-upN">
<items>
<menuItem title="Undo" keyEquivalent="z" id="Ueo-Yj-fzm">
<connections>
<action selector="undo:" target="-1" id="Ex2-6U-hZI"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="x6z-iQ-VK2">
<connections>
<action selector="redo:" target="-1" id="KEx-Aj-tYn"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="COi-E7-7M4"/>
<menuItem title="Cut" keyEquivalent="x" id="NAk-12-pg4">
<connections>
<action selector="cut:" target="-1" id="Owu-Ie-Kfg"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="XOY-ya-lNt">
<connections>
<action selector="copy:" target="-1" id="aIB-pV-N2w"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="ul0-51-Ibd">
<connections>
<action selector="paste:" target="-1" id="7rk-Tb-7hI"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="Zvy-7g-x4q">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="-1" id="oM4-kj-hTQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="Xyz-QC-wlG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="-1" id="idJ-aN-6bB"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="4fT-JL-N6e">
<connections>
<action selector="selectAll:" target="-1" id="pAH-rW-PaD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="osB-R6-2jE"/>
<menuItem title="Find" id="bms-8x-7Yb">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="AXr-4L-lcV">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="GS8-y9-yQY">
<connections>
<action selector="performFindPanelAction:" target="-1" id="jVT-dG-Frl"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="RJc-P7-Ibq">
<connections>
<action selector="performFindPanelAction:" target="-1" id="yLp-2a-Nuk"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="f5k-Su-hK0">
<connections>
<action selector="performFindPanelAction:" target="-1" id="uoF-9Z-ef7"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="9Zj-Be-aBN">
<connections>
<action selector="performFindPanelAction:" target="-1" id="8hs-AK-0U8"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="4tD-ef-pd8">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="8xc-J0-7iQ"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="83"/>
<menuItem title="Player" id="633">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Screen" id="295"/>
<menuItem title="Window" id="19">
<menu key="submenu" title="Window" systemMenu="window" id="XuB-dT-g0h">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="YrK-j5-jxq">
<connections>
<action selector="performMiniaturize:" target="-1" id="3wr-0O-cTq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="0NY-jh-tsl">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Bring All to Front" id="opb-EX-EXV">
<connections>
<action selector="arrangeInFront:" target="-1" id="oT1-07-BON"/>
</connections>
</menuItem>
<menuItem title="Always On Top" keyEquivalent="a" id="nXh-Uq-d6d">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="onWindowAlwaysOnTop:" target="-1" id="IM6-Km-MGj"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="490">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="UaO-03-xh1">
<items>
<menuItem title="simulator Help" keyEquivalent="?" id="StN-Og-Ms8">
<connections>
<action selector="showHelp:" target="-1" id="l0h-I0-XAk"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<customObject id="420" customClass="NSFontManager"/>
<customObject id="536" customClass="AppController">
<connections>
<outlet property="menu" destination="29" id="550"/>
</connections>
</customObject>
</objects>
</document>

View File

@ -24,29 +24,35 @@
#include <string>
#import <Cocoa/Cocoa.h>
#import "service/ConsoleWindowController.h"
#include "ProjectConfig/ProjectConfig.h"
#include "ProjectConfig/SimulatorConfig.h"
#include "AppDelegate.h"
void createSimulator(const char* viewName, float width, float height,bool isLandscape = true,float frameZoomFactor = 1.0f);
@interface AppController : NSObject <NSApplicationDelegate, NSWindowDelegate>
@interface AppController : NSObject <NSApplicationDelegate, NSWindowDelegate, NSFileManagerDelegate>
{
NSWindow *window;
NSWindow *_window;
NSMenu *menu;
NSFileHandle *fileHandle;
AppDelegate *_app;
ProjectConfig _project;
int _debugLogFile;
//log file
ConsoleWindowController *_consoleController;
NSFileHandle *_fileHandle;
//console pipe
NSPipe *pipe;
NSFileHandle *pipeReadHandle;
NSPipe *_pipe;
NSFileHandle *_pipeReadHandle;
}
@property (nonatomic, assign) IBOutlet NSMenu* menu;
- (IBAction) onSetTop:(id)sender;
- (IBAction) onFileClose:(id)sender;
- (IBAction) onScreenPortait:(id)sender;
- (IBAction) onScreenLandscape:(id)sender;
- (IBAction) onScreenZoomOut:(id)sender;
- (IBAction) onRelaunch:(id)sender;
-(IBAction)onFileClose:(id)sender;
-(IBAction)onWindowAlwaysOnTop:(id)sender;
@end

View File

@ -36,15 +36,19 @@
#include "ConfigParser.h"
#include "cocos2d.h"
#include "CCLuaEngine.h"
#include "CodeIDESupport.h"
using namespace cocos2d;
#include "service/PlayerMac.h"
#include "service/AppEvent.h"
#include "service/AppLang.h"
bool g_landscape = false;
bool g_windTop = false;
cocos2d::Size g_screenSize;
GLViewImpl* g_eglView = nullptr;
static AppController* g_nsAppDelegate=nullptr;
#if (GLFW_VERSION_MAJOR >= 3) && (GLFW_VERSION_MINOR >= 1)
#define PLAYER_SUPPORT_DROP 1
#else
#define PLAYER_SUPPORT_DROP 0
#endif
using namespace std;
using namespace cocos2d;
@ -68,6 +72,17 @@ std::string getCurAppName(void)
return appName;
}
#if (PLAYER_SUPPORT_DROP > 0)
static void glfwDropFunc(GLFWwindow *window, int count, const char **files)
{
AppEvent forwardEvent(kAppEventDropName, APP_EVENT_DROP);
std::string firstFile(files[0]);
forwardEvent.setDataString(firstFile);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&forwardEvent);
}
#endif
-(void) dealloc
{
Director::getInstance()->end();
@ -79,226 +94,118 @@ std::string getCurAppName(void)
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSArray *args = [[NSProcessInfo processInfo] arguments];
auto player = player::PlayerMac::create();
player->setController(self);
if (args != nullptr && [args count] >= 2) {
}
g_nsAppDelegate = self;
AppDelegate app;
Application::getInstance()->run();
// After run, application needs to be terminated immediately.
[[NSApplication sharedApplication] terminate: self];
_debugLogFile = 0;
[self parseCocosProjectConfig:&_project];
[self updateProjectFromCommandLineArgs:&_project];
[self createWindowAndGLView];
[self startup];
}
#pragma mark -
#pragma mark functions
- (void) createSimulator:(NSString*)viewName viewWidth:(float)width viewHeight:(float)height factor:(float)frameZoomFactor
{
if (g_eglView)
{
return;
}
if(!g_landscape)
{
float tmpvalue =width;
width = height;
height = tmpvalue;
}
g_windTop = ConfigParser::getInstance()->isWindowTop();
g_eglView = GLViewImpl::createWithRect([viewName cStringUsingEncoding:NSUTF8StringEncoding],cocos2d::Rect(0.0f,0.0f,width,height),frameZoomFactor);
auto director = Director::getInstance();
director->setOpenGLView(g_eglView);
window = glfwGetCocoaWindow(g_eglView->getWindow());
[[NSApplication sharedApplication] setDelegate: self];
[self createViewMenu];
[self updateMenu];
[window center];
[window becomeFirstResponder];
[window makeKeyAndOrderFront:self];
}
void createSimulator(const char* viewName, float width, float height,bool isLandscape,float frameZoomFactor)
{
if(g_nsAppDelegate)
{
g_landscape = isLandscape;
if(height > width)
{
float tmpvalue =width;
width = height;
height = tmpvalue;
}
g_screenSize.width = width;
g_screenSize.height = height;
[g_nsAppDelegate createSimulator:[NSString stringWithUTF8String:viewName] viewWidth:width viewHeight:height factor:frameZoomFactor];
}
}
- (void) createViewMenu
{
NSMenu *submenu = [[[window menu] itemWithTitle:@"View"] submenu];
for (int i = ConfigParser::getInstance()->getScreenSizeCount() - 1; i >= 0; --i)
{
SimulatorScreenSize size = ConfigParser::getInstance()->getScreenSize(i);
NSMenuItem *item = [[[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:size.title.c_str() encoding:NSUTF8StringEncoding]
action:@selector(onViewChangeFrameSize:)
keyEquivalent:@""] autorelease];
[item setTag:i];
[submenu insertItem:item atIndex:0];
}
}
- (void) updateMenu
{
NSMenu *menuScreen = [[[window menu] itemWithTitle:@"View"] submenu];
NSMenuItem *itemPortait = [menuScreen itemWithTitle:@"Portait"];
NSMenuItem *itemLandscape = [menuScreen itemWithTitle:@"Landscape"];
if (g_landscape)
{
[itemPortait setState:NSOffState];
[itemLandscape setState:NSOnState];
}
else
{
[itemPortait setState:NSOnState];
[itemLandscape setState:NSOffState];
}
NSMenu *menuControl = [[[window menu] itemWithTitle:@"Control"] submenu];
NSMenuItem *itemTop = [menuControl itemWithTitle:@"Keep Window Top"];
if (g_windTop) {
[window setLevel:NSFloatingWindowLevel];
[itemTop setState:NSOnState];
}
else
{
[window setLevel:NSNormalWindowLevel];
[itemTop setState:NSOffState];
}
int scale = g_eglView->getFrameZoomFactor()*100;
NSMenuItem *itemZoom100 = [menuScreen itemWithTitle:@"Actual (100%)"];
NSMenuItem *itemZoom75 = [menuScreen itemWithTitle:@"Zoom Out (75%)"];
NSMenuItem *itemZoom50 = [menuScreen itemWithTitle:@"Zoom Out (50%)"];
NSMenuItem *itemZoom25 = [menuScreen itemWithTitle:@"Zoom Out (25%)"];
[itemZoom100 setState:NSOffState];
[itemZoom75 setState:NSOffState];
[itemZoom50 setState:NSOffState];
[itemZoom25 setState:NSOffState];
if (scale == 100)
{
[itemZoom100 setState:NSOnState];
}
else if (scale == 75)
{
[itemZoom75 setState:NSOnState];
}
else if (scale == 50)
{
[itemZoom50 setState:NSOnState];
}
else if (scale == 25)
{
[itemZoom25 setState:NSOnState];
}
int width = g_screenSize.width;
int height = g_screenSize.height;
if (height > width)
{
int w = width;
width = height;
height = w;
}
int count = ConfigParser::getInstance()->getScreenSizeCount();
for (int i = 0; i < count; ++i)
{
bool bSel = false;
SimulatorScreenSize size = ConfigParser::getInstance()->getScreenSize(i);
if (size.width == width && size.height == height)
{
bSel = true;
}
NSMenuItem *itemView = [menuScreen itemWithTitle:[NSString stringWithUTF8String:size.title.c_str()]];
[itemView setState:(bSel? NSOnState : NSOffState)];
}
}
- (void) updateView
{
auto policy = g_eglView->getResolutionPolicy();
auto designSize = g_eglView->getDesignResolutionSize();
if (g_landscape)
{
g_eglView->setFrameSize(g_screenSize.width, g_screenSize.height);
}
else
{
g_eglView->setFrameSize(g_screenSize.height, g_screenSize.width);
}
g_eglView->setDesignResolutionSize(designSize.width, designSize.height, policy);
[self updateMenu];
}
- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
- (BOOL) windowShouldClose:(id)sender
{
return YES;
}
- (BOOL) applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
{
return NO;
}
- (void) windowWillClose:(NSNotification *)notification
{
[[NSRunningApplication currentApplication] terminate];
}
- (IBAction) onSetTop:(id)sender
- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
{
g_windTop = !g_windTop;
[self updateMenu];
return YES;
}
- (IBAction) onFileClose:(id)sender
- (NSMutableArray*) makeCommandLineArgsFromProjectConfig
{
[[NSApplication sharedApplication] terminate:self];
return [self makeCommandLineArgsFromProjectConfig:kProjectConfigAll];
}
- (IBAction) onScreenPortait:(id)sender
- (NSMutableArray*) makeCommandLineArgsFromProjectConfig:(unsigned int)mask
{
g_landscape = false;
[self updateView];
_project.setWindowOffset(Vec2(_window.frame.origin.x, _window.frame.origin.y));
vector<string> args = _project.makeCommandLineVector();
NSMutableArray *commandArray = [NSMutableArray arrayWithCapacity:args.size()];
for (auto &path : args)
{
[commandArray addObject:[NSString stringWithUTF8String:path.c_str()]];
}
return commandArray;
}
- (IBAction) onScreenLandscape:(id)sender
- (void) parseCocosProjectConfig:(ProjectConfig*)config
{
g_landscape = true;
[self updateView];
// get project directory
ProjectConfig tmpConfig;
NSArray *nsargs = [[NSProcessInfo processInfo] arguments];
long n = [nsargs count];
if (n >= 2)
{
vector<string> args;
for (int i = 0; i < [nsargs count]; ++i)
{
string arg = [[nsargs objectAtIndex:i] cStringUsingEncoding:NSUTF8StringEncoding];
if (arg.length()) args.push_back(arg);
}
if (args.size() && args.at(1).at(0) == '/')
{
// FIXME:
// for Code IDE before RC2
tmpConfig.setProjectDir(args.at(1));
}
tmpConfig.parseCommandLine(args);
}
// set project directory as search root path
FileUtils::getInstance()->setDefaultResourceRootPath(tmpConfig.getProjectDir());
// parse config.json
auto parser = ConfigParser::getInstance();
auto configPath = tmpConfig.getProjectDir().append(CONFIG_FILE);
parser->readConfig(configPath);
// set information
config->setConsolePort(parser->getConsolePort());
config->setFileUploadPort(parser->getUploadPort());
config->setFrameSize(parser->getInitViewSize());
if (parser->isLanscape())
{
config->changeFrameOrientationToLandscape();
}
config->setScriptFile(parser->getEntryFile());
}
- (void) updateProjectFromCommandLineArgs:(ProjectConfig*)config
{
NSArray *nsargs = [[NSProcessInfo processInfo] arguments];
long n = [nsargs count];
if (n >= 2)
{
vector<string> args;
for (int i = 0; i < [nsargs count]; ++i)
{
string arg = [[nsargs objectAtIndex:i] cStringUsingEncoding:NSUTF8StringEncoding];
if (arg.length()) args.push_back(arg);
}
if (args.size() && args.at(1).at(0) == '/')
{
// for Code IDE before RC2
config->setProjectDir(args.at(1));
config->setDebuggerType(kCCRuntimeDebuggerCodeIDE);
}
config->parseCommandLine(args);
}
}
- (void) launch:(NSArray*)args
@ -308,7 +215,8 @@ void createSimulator(const char* viewName, float width, float height,bool isLand
NSError *error = [[[NSError alloc] init] autorelease];
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:url
options:NSWorkspaceLaunchNewInstance
configuration:configuration error:&error];
configuration:configuration
error:&error];
}
- (void) relaunch:(NSArray*)args
@ -317,33 +225,372 @@ void createSimulator(const char* viewName, float width, float height,bool isLand
[[NSApplication sharedApplication] terminate:self];
}
- (IBAction) onRelaunch:(id)sender
- (void) relaunch
{
NSArray* args=[[NSArray alloc] initWithObjects:@" ", nil];
[self relaunch:args];
[self relaunch:[self makeCommandLineArgsFromProjectConfig]];
}
- (IBAction) onViewChangeFrameSize:(id)sender
- (void) createWindowAndGLView
{
NSInteger index = [sender tag];
if (index >= 0 && index < ConfigParser::getInstance()->getScreenSizeCount())
GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
GLView::setGLContextAttrs(glContextAttrs);
// create console window **MUST** before create opengl view
if (_project.isShowConsole())
{
SimulatorScreenSize size = ConfigParser::getInstance()->getScreenSize(index);
g_screenSize.width = size.width;
g_screenSize.height = size.height;
[self updateView];
[self openConsoleWindow];
CCLOG("%s\n",Configuration::getInstance()->getInfo().c_str());
}
float frameScale = _project.getFrameScale();
// create opengl view
cocos2d::Size frameSize = _project.getFrameSize();
const cocos2d::Rect frameRect = cocos2d::Rect(0, 0, frameSize.width, frameSize.height);
std::stringstream title;
title << "Cocos Simulator - " << ConfigParser::getInstance()->getInitViewName();
GLViewImpl *eglView = GLViewImpl::createWithRect(title.str(), frameRect, frameScale);
auto director = Director::getInstance();
director->setOpenGLView(eglView);
_window = eglView->getCocoaWindow();
[[NSApplication sharedApplication] setDelegate: self];
[_window center];
if (_project.getProjectDir().length())
{
[self setZoom:_project.getFrameScale()];
Vec2 pos = _project.getWindowOffset();
if (pos.x != 0 && pos.y != 0)
{
[_window setFrameOrigin:NSMakePoint(pos.x, pos.y)];
}
}
#if (PLAYER_SUPPORT_DROP > 0)
glfwSetDropCallback(eglView->getWindow(), glfwDropFunc);
#endif
}
- (void) adjustEditMenuIndex
{
NSApplication *thisApp = [NSApplication sharedApplication];
NSMenu *mainMenu = [thisApp mainMenu];
NSMenuItem *editMenuItem = [mainMenu itemWithTitle:@"Edit"];
if (editMenuItem)
{
NSUInteger index = 2;
if (index > [mainMenu itemArray].count)
index = [mainMenu itemArray].count;
[[editMenuItem menu] removeItem:editMenuItem];
[mainMenu insertItem:editMenuItem atIndex:index];
}
}
- (void) startup
{
FileUtils::getInstance()->setPopupNotify(false);
_project.dump();
const string projectDir = _project.getProjectDir();
if (projectDir.length())
{
FileUtils::getInstance()->setDefaultResourceRootPath(projectDir);
if (_project.isWriteDebugLogToFile())
{
[self writeDebugLogToFile:_project.getDebugLogFilePath()];
}
}
const string writablePath = _project.getWritableRealPath();
if (writablePath.length())
{
FileUtils::getInstance()->setWritablePath(writablePath.c_str());
}
// path for looking Lang file, Studio Default images
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
FileUtils::getInstance()->addSearchPath(resourcePath.UTF8String);
// app
_app = new AppDelegate();
[self setupUI];
[self adjustEditMenuIndex];
_app->setProjectConfig(_project);
Application::getInstance()->run();
// After run, application needs to be terminated immediately.
[NSApp terminate: self];
}
- (void) setupUI
{
auto menuBar = player::PlayerProtocol::getInstance()->getMenuService();
// VIEW
menuBar->addItem("VIEW_MENU", tr("View"));
SimulatorConfig *config = SimulatorConfig::getInstance();
int current = config->checkScreenSize(_project.getFrameSize());
for (int i = 0; i < config->getScreenSizeCount(); i++)
{
SimulatorScreenSize size = config->getScreenSize(i);
std::stringstream menuId;
menuId << "VIEWSIZE_ITEM_MENU_" << i;
auto menuItem = menuBar->addItem(menuId.str(), size.title.c_str(), "VIEW_MENU");
if (i == current)
{
menuItem->setChecked(true);
}
}
menuBar->addItem("DIRECTION_MENU_SEP", "-", "VIEW_MENU");
menuBar->addItem("DIRECTION_PORTRAIT_MENU", tr("Portrait"), "VIEW_MENU")
->setChecked(_project.isPortraitFrame());
menuBar->addItem("DIRECTION_LANDSCAPE_MENU", tr("Landscape"), "VIEW_MENU")
->setChecked(_project.isLandscapeFrame());
menuBar->addItem("VIEW_SCALE_MENU_SEP", "-", "VIEW_MENU");
std::vector<player::PlayerMenuItem*> scaleMenuVector;
auto scale100Menu = menuBar->addItem("VIEW_SCALE_MENU_100", tr("Zoom Out").append(" (100%)"), "VIEW_MENU");
scale100Menu->setShortcut("super+0");
auto scale75Menu = menuBar->addItem("VIEW_SCALE_MENU_75", tr("Zoom Out").append(" (75%)"), "VIEW_MENU");
scale75Menu->setShortcut("super+7");
auto scale50Menu = menuBar->addItem("VIEW_SCALE_MENU_50", tr("Zoom Out").append(" (50%)"), "VIEW_MENU");
scale50Menu->setShortcut("super+6");
auto scale25Menu = menuBar->addItem("VIEW_SCALE_MENU_25", tr("Zoom Out").append(" (25%)"), "VIEW_MENU");
scale25Menu->setShortcut("super+5");
int frameScale = int(_project.getFrameScale() * 100);
if (frameScale == 100)
{
scale100Menu->setChecked(true);
}
else if (frameScale == 75)
{
scale75Menu->setChecked(true);
}
else if (frameScale == 50)
{
scale50Menu->setChecked(true);
}
else if (frameScale == 25)
{
scale25Menu->setChecked(true);
}
else
{
scale100Menu->setChecked(true);
}
scaleMenuVector.push_back(scale100Menu);
scaleMenuVector.push_back(scale75Menu);
scaleMenuVector.push_back(scale50Menu);
scaleMenuVector.push_back(scale25Menu);
menuBar->addItem("REFRESH_MENU_SEP", "-", "VIEW_MENU");
menuBar->addItem("REFRESH_MENU", tr("Refresh"), "VIEW_MENU")->setShortcut("super+r");
ProjectConfig &project = _project;
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->addEventListenerWithFixedPriority(EventListenerCustom::create(kAppEventName, [&project, scaleMenuVector](EventCustom* event){
auto menuEvent = dynamic_cast<AppEvent*>(event);
if (menuEvent)
{
rapidjson::Document dArgParse;
dArgParse.Parse<0>(menuEvent->getDataString().c_str());
if (dArgParse.HasMember("name"))
{
string strcmd = dArgParse["name"].GetString();
if (strcmd == "menuClicked")
{
player::PlayerMenuItem *menuItem = static_cast<player::PlayerMenuItem*>(menuEvent->getUserData());
if (menuItem)
{
if (menuItem->isChecked())
{
return ;
}
string data = dArgParse["data"].GetString();
auto player = player::PlayerProtocol::getInstance();
if ((data == "CLOSE_MENU") || (data == "EXIT_MENU"))
{
player->quit();
}
else if (data == "REFRESH_MENU")
{
player->relaunch();
}
else if (data.find("VIEW_SCALE_MENU_") == 0) // begin with VIEW_SCALE_MENU_
{
string tmp = data.erase(0, strlen("VIEW_SCALE_MENU_"));
float scale = atof(tmp.c_str()) / 100.0f;
project.setFrameScale(scale);
auto glview = static_cast<GLViewImpl*>(Director::getInstance()->getOpenGLView());
glview->setFrameZoomFactor(scale);
// update scale menu state
for (auto &it : scaleMenuVector)
{
it->setChecked(false);
}
menuItem->setChecked(true);
}
else if (data.find("VIEWSIZE_ITEM_MENU_") == 0) // begin with VIEWSIZE_ITEM_MENU_
{
string tmp = data.erase(0, strlen("VIEWSIZE_ITEM_MENU_"));
int index = atoi(tmp.c_str());
SimulatorScreenSize size = SimulatorConfig::getInstance()->getScreenSize(index);
if (project.isLandscapeFrame())
{
std::swap(size.width, size.height);
}
project.setFrameSize(cocos2d::Size(size.width, size.height));
project.setWindowOffset(cocos2d::Vec2(player->getPositionX(), player->getPositionY()));
player->openProjectWithProjectConfig(project);
}
else if (data == "DIRECTION_PORTRAIT_MENU")
{
project.changeFrameOrientationToPortait();
player->openProjectWithProjectConfig(project);
}
else if (data == "DIRECTION_LANDSCAPE_MENU")
{
project.changeFrameOrientationToLandscape();
player->openProjectWithProjectConfig(project);
}
}
}
}
}
}), 1);
// drop
AppDelegate *app = _app;
auto listener = EventListenerCustom::create(kAppEventDropName, [&project, app](EventCustom* event)
{
AppEvent *dropEvent = dynamic_cast<AppEvent*>(event);
if (dropEvent)
{
string dirPath = dropEvent->getDataString() + "/";
string configFilePath = dirPath + CONFIG_FILE;
if (FileUtils::getInstance()->isDirectoryExist(dirPath) &&
FileUtils::getInstance()->isFileExist(configFilePath))
{
// parse config.json
ConfigParser::getInstance()->readConfig(configFilePath);
project.setProjectDir(dirPath);
project.setScriptFile(ConfigParser::getInstance()->getEntryFile());
project.setWritablePath(dirPath);
app->setProjectConfig(project);
app->reopenProject();
}
}
});
dispatcher->addEventListenerWithFixedPriority(listener, 1);
}
- (void) openConsoleWindow
{
if (!_consoleController)
{
_consoleController = [[ConsoleWindowController alloc] initWithWindowNibName:@"ConsoleWindow"];
}
[_consoleController.window orderFrontRegardless];
//set console pipe
_pipe = [NSPipe pipe] ;
_pipeReadHandle = [_pipe fileHandleForReading] ;
int outfd = [[_pipe fileHandleForWriting] fileDescriptor];
if (dup2(outfd, fileno(stderr)) != fileno(stderr) || dup2(outfd, fileno(stdout)) != fileno(stdout))
{
perror("Unable to redirect output");
// [self showAlert:@"Unable to redirect output to console!" withTitle:@"player error"];
}
else
{
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNotification:) name: NSFileHandleReadCompletionNotification object: _pipeReadHandle] ;
[_pipeReadHandle readInBackgroundAndNotify] ;
}
}
- (IBAction) onScreenZoomOut:(id)sender
- (bool) writeDebugLogToFile:(const string)path
{
if ([sender state] == NSOnState) return;
float scale = (float)[sender tag] / 100.0f;
g_eglView->setFrameZoomFactor(scale);
[self updateView];
if (_debugLogFile) return true;
//log to file
if(_fileHandle) return true;
NSString *fPath = [NSString stringWithCString:path.c_str() encoding:[NSString defaultCStringEncoding]];
[[NSFileManager defaultManager] createFileAtPath:fPath contents:nil attributes:nil] ;
_fileHandle = [NSFileHandle fileHandleForWritingAtPath:fPath];
[_fileHandle retain];
return true;
}
- (void)handleNotification:(NSNotification *)note
{
//NSLog(@"Received notification: %@", note);
[_pipeReadHandle readInBackgroundAndNotify] ;
NSData *data = [[note userInfo] objectForKey:NSFileHandleNotificationDataItem];
NSString *str = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
//show log to console
[_consoleController trace:str];
if(_fileHandle!=nil){
[_fileHandle writeData:[str dataUsingEncoding:NSUTF8StringEncoding]];
}
}
- (void) setZoom:(float)scale
{
Director::getInstance()->getOpenGLView()->setFrameZoomFactor(scale);
_project.setFrameScale(scale);
}
- (BOOL) applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
{
return NO;
}
#pragma mark -
-(IBAction)onFileClose:(id)sender
{
[[NSApplication sharedApplication] terminate:self];
}
-(IBAction)onWindowAlwaysOnTop:(id)sender
{
NSInteger state = [sender state];
if (state == NSOffState)
{
[_window setLevel:NSFloatingWindowLevel];
[sender setState:NSOnState];
}
else
{
[_window setLevel:NSNormalWindowLevel];
[sender setState:NSOffState];
}
}
@end

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6254"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ConsoleWindowController">
<connections>
<outlet property="checkScroll" destination="50" id="70"/>
<outlet property="textView" destination="6" id="20"/>
<outlet property="topCheckBox" destination="60" id="69"/>
<outlet property="window" destination="1" id="3"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Console" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" animationBehavior="default" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="40" y="40" width="854" height="400"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="854" height="400"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="-1" y="-1" width="854" height="371"/>
<clipView key="contentView" id="ddW-qo-Qe9">
<rect key="frame" x="1" y="1" width="837" height="369"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView editable="NO" importsGraphics="NO" richText="NO" findStyle="panel" verticallyResizable="YES" allowsNonContiguousLayout="YES" id="6">
<rect key="frame" x="0.0" y="0.0" width="837" height="369"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="837" height="369"/>
<size key="maxSize" width="888" height="10000000"/>
<color key="insertionPointColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="837" height="369"/>
<size key="maxSize" width="888" height="10000000"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="7">
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="8">
<rect key="frame" x="838" y="1" width="15" height="369"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="46">
<rect key="frame" x="-1" y="367" width="73" height="32"/>
<buttonCell key="cell" type="push" title="Clear" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="47">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="onClear:" target="-2" id="57"/>
</connections>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="50">
<rect key="frame" x="731" y="376" width="113" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="109" id="56"/>
</constraints>
<buttonCell key="cell" type="check" title="scroll bottom" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="51">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="onScrollChange:" target="-2" id="59"/>
</connections>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="60">
<rect key="frame" x="632" y="375" width="95" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="91" id="64"/>
</constraints>
<buttonCell key="cell" type="check" title="always top" bezelStyle="regularSquare" imagePosition="left" inset="2" id="61">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="onTopChange:" target="-2" id="67"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="5" secondAttribute="trailing" constant="1" id="41"/>
<constraint firstAttribute="bottom" secondItem="5" secondAttribute="bottom" constant="-1" id="42"/>
<constraint firstItem="5" firstAttribute="top" secondItem="2" secondAttribute="top" constant="30" id="43"/>
<constraint firstItem="5" firstAttribute="leading" secondItem="2" secondAttribute="leading" constant="-1" id="44"/>
<constraint firstItem="46" firstAttribute="leading" secondItem="2" secondAttribute="leading" constant="5" id="49"/>
<constraint firstItem="50" firstAttribute="baseline" secondItem="46" secondAttribute="baseline" id="52"/>
<constraint firstAttribute="trailing" secondItem="50" secondAttribute="trailing" constant="12" id="53"/>
<constraint firstItem="5" firstAttribute="top" secondItem="50" secondAttribute="bottom" constant="8" symbolic="YES" id="54"/>
<constraint firstItem="60" firstAttribute="centerY" secondItem="46" secondAttribute="centerY" id="63"/>
<constraint firstItem="50" firstAttribute="leading" secondItem="60" secondAttribute="trailing" constant="8" symbolic="YES" id="66"/>
</constraints>
</view>
<connections>
<outlet property="delegate" destination="-2" id="4"/>
</connections>
</window>
</objects>
</document>

View File

@ -0,0 +1,23 @@
#import <Cocoa/Cocoa.h>
@interface ConsoleWindowController : NSWindowController
{
NSTextView *textView;
IBOutlet NSButton *checkScroll;
IBOutlet NSButton *topCheckBox;
NSMutableArray *linesCount;
NSUInteger traceCount;
}
@property (assign) IBOutlet NSTextView *textView;
- (void) trace:(NSString*)msg;
- (IBAction)onClear:(id)sender;
- (IBAction)onScrollChange:(id)sender;
- (IBAction)onTopChange:(id)sender;
@end

View File

@ -0,0 +1,100 @@
#import "ConsoleWindowController.h"
@interface ConsoleWindowController ()
@end
#define SKIP_LINES_COUNT 3
#define MAX_LINE_LEN 4096
#define MAX_LINES_COUNT 200
@implementation ConsoleWindowController
@synthesize textView;
- (id)initWithWindow:(NSWindow *)window
{
self = [super initWithWindow:window];
if (self)
{
// Initialization code here.
linesCount = [[NSMutableArray arrayWithCapacity:MAX_LINES_COUNT + 1] retain];
}
return self;
}
- (void)dealloc
{
[linesCount release];
[super dealloc];
}
- (void)windowDidLoad
{
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
- (void) trace:(NSString*)msg
{
if (traceCount >= SKIP_LINES_COUNT && [msg length] > MAX_LINE_LEN)
{
msg = [NSString stringWithFormat:@"%@ ...", [msg substringToIndex:MAX_LINE_LEN - 4]];
}
traceCount++;
NSFont *font = [NSFont fontWithName:@"Monaco" size:12.0];
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
NSAttributedString *string = [[NSAttributedString alloc] initWithString:msg attributes:attrsDictionary];
NSNumber *len = [NSNumber numberWithUnsignedInteger:[string length]];
[linesCount addObject:len];
NSTextStorage *storage = [textView textStorage];
[storage beginEditing];
[storage appendAttributedString:string];
if ([linesCount count] >= MAX_LINES_COUNT)
{
len = [linesCount objectAtIndex:0];
[storage deleteCharactersInRange:NSMakeRange(0, [len unsignedIntegerValue])];
[linesCount removeObjectAtIndex:0];
}
[storage endEditing];
[self changeScroll];
}
- (void) changeScroll
{
BOOL scroll = [checkScroll state] == NSOnState;
if(scroll)
{
[self.textView scrollRangeToVisible: NSMakeRange(self.textView.string.length, 0)];
}
}
- (IBAction)onClear:(id)sender
{
NSTextStorage *storage = [textView textStorage];
[storage setAttributedString:[[[NSAttributedString alloc] initWithString:@""] autorelease]];
}
- (IBAction)onScrollChange:(id)sender
{
[self changeScroll];
}
- (IBAction)onTopChange:(id)sender
{
BOOL isTop = [topCheckBox state] == NSOnState;
if(isTop)
{
[self.window setLevel:NSFloatingWindowLevel];
}
else
{
[self.window setLevel:NSNormalWindowLevel];
}
}
@end

View File

@ -0,0 +1,70 @@
#include "DeviceEx.h"
#import "openudid/OpenUDIDMac.h"
using namespace std;
PLAYER_NS_BEGIN
DeviceEx *DeviceEx::getInstance()
{
static DeviceEx *instance = NULL;
if (!instance)
{
instance = new DeviceEx();
instance->init();
}
return instance;
}
std::string DeviceEx::getCurrentUILangName()
{
return _uiLangName;
}
std::string DeviceEx::getUserGUID()
{
return _userGUID;
}
////////// private //////////
DeviceEx::DeviceEx()
: _uiLangName("en")
{
}
void DeviceEx::init()
{
makeUILangName();
makeUserGUID();
}
void DeviceEx::makeUILangName()
{
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
NSArray *languages = [defs objectForKey:@"AppleLanguages"];
if ([languages count] > 0)
{
NSString *lang = [languages objectAtIndex:0];
_uiLangName = lang.UTF8String;
}
}
std::string DeviceEx::makeUserGUID()
{
if (_userGUID.length() <= 0)
{
_userGUID = string([[OpenUDIDMac value] cStringUsingEncoding:NSUTF8StringEncoding]);
if (_userGUID.length() <= 0)
{
_userGUID = "guid-fixed-1234567890";
}
}
return _userGUID;
}
PLAYER_NS_END

View File

@ -0,0 +1,61 @@
//
// EditBoxServiceMac.h
// player
//
#ifndef __player__EditBoxServiceMac__
#define __player__EditBoxServiceMac__
#include "PlayerEditBoxServiceProtocol.h"
@interface EditBoxServiceImplMac : NSObject <NSTextFieldDelegate>
{
void* editBox_;
BOOL editState_;
NSMutableDictionary* placeholderAttributes_;
}
@property(nonatomic, retain) NSTextField* textField;
@property(nonatomic, retain) NSMutableDictionary* placeholderAttributes;
@property(nonatomic, readonly, getter = isEditState) BOOL editState;
@property(nonatomic, assign) void* editBox;
-(id) initWithFrame: (NSRect) frameRect editBox: (void*) editBox;
-(void) doAnimationWhenKeyboardMoveWithDuration:(float)duration distance:(float)distance;
-(void) setPosition:(NSPoint) pos;
-(void) setContentSize:(NSSize) size;
-(void) visit;
-(void) openKeyboard;
-(void) closeKeyboard;
@end
PLAYER_NS_BEGIN
class PlayerEditBoxServiceMac : public PlayerEditBoxServiceProtocol
{
public:
PlayerEditBoxServiceMac();
virtual ~PlayerEditBoxServiceMac();
// overwrite
virtual void showSingleLineEditBox(const cocos2d::Rect &rect) ;
virtual void showMultiLineEditBox(const cocos2d::Rect &rect) ;
virtual void hide() ;
virtual void setText(const std::string &text);
virtual void setFont(const std::string &name, int size);
virtual void setFontColor(const cocos2d::Color3B &color);
virtual void setFormator(int formator);
private:
void show();
private:
EditBoxServiceImplMac* _sysEdit;
};
PLAYER_NS_END
#endif

View File

@ -0,0 +1,226 @@
#include "PlayerEditBoxServiceMac.h"
#include "cocos2d.h"
#include "CCLuaEngine.h"
#include "glfw3native.h"
// internal
@implementation EditBoxServiceImplMac
@synthesize textField = textField_;
@synthesize placeholderAttributes = placeholderAttributes_;
@synthesize editState = editState_;
@synthesize editBox = editBox_;
- (id) getNSWindow
{
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
return glview->getCocoaWindow();
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[textField_ removeFromSuperview];
[textField_ release];
[placeholderAttributes_ release];
[super dealloc];
}
-(id) initWithFrame: (NSRect) frameRect editBox: (void*) editBox
{
self = [super init];
if (self)
{
editState_ = NO;
self.textField = [[[NSTextField alloc] initWithFrame:frameRect] autorelease];
NSColor *newColor = [NSColor colorWithCalibratedRed:255 / 255.0f green:0 blue:0 alpha:1.0f];
self.textField.textColor = newColor;
NSFont *font = [NSFont systemFontOfSize:10]; //TODO need to delete hard code here.
textField_.font = font;
[self setupTextField:textField_];
self.editBox = editBox;
self.placeholderAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
font, NSFontAttributeName,
[NSColor grayColor], NSForegroundColorAttributeName,
nil];
[[[self getNSWindow] contentView] addSubview:textField_];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onTextDidChanged:)
name:NSControlTextDidEndEditingNotification
object:nil];
}
return self;
}
- (void)onTextDidChanged:(NSNotification *) notification
{
// hide first
[self.textField setHidden:YES];
player::PlayerEditBoxServiceMac *macEditBox = static_cast<player::PlayerEditBoxServiceMac *>(self.editBox);
auto luaStack = cocos2d::LuaEngine::getInstance()->getLuaStack();
luaStack->pushString([self.textField.stringValue UTF8String]);
luaStack->executeFunctionByHandler(macEditBox->getHandler(), 1);
}
- (void)setupTextField:(NSTextField *)textField
{
[textField setTextColor:[NSColor whiteColor]];
[textField setBackgroundColor:[NSColor clearColor]];
[textField setBordered:NO];
[textField setHidden:NO];
[textField setWantsLayer:YES];
[textField setDelegate:self];
}
-(void) doAnimationWhenKeyboardMoveWithDuration:(float)duration distance:(float)distance
{
[[[self getNSWindow] contentView] doAnimationWhenKeyboardMoveWithDuration:duration distance:distance];
}
-(void) setPosition:(NSPoint) pos
{
NSRect frame = [textField_ frame];
frame.origin = pos;
[textField_ setFrame:frame];
}
-(void) setContentSize:(NSSize) size
{
[self.textField setFrameSize:size];
}
-(void) visit
{
}
-(void) openKeyboard
{
if ([textField_ superview]) {
[textField_ becomeFirstResponder];
}
}
-(void) closeKeyboard
{
if ([textField_ superview]) {
[textField_ resignFirstResponder];
}
}
- (BOOL)textFieldShouldReturn:(NSTextField *)sender
{
if (sender == textField_) {
[sender resignFirstResponder];
}
return NO;
}
-(void)animationSelector
{
}
- (BOOL) control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
{
return NO;
}
@end
PLAYER_NS_BEGIN;
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
PlayerEditBoxServiceMac::PlayerEditBoxServiceMac()
{
_handler = 0;
NSRect rect = NSMakeRect(0, 0, 100, 20);
_sysEdit = [[EditBoxServiceImplMac alloc] initWithFrame:rect editBox:this];
}
PlayerEditBoxServiceMac::~PlayerEditBoxServiceMac()
{
[_sysEdit release];
}
void PlayerEditBoxServiceMac::showSingleLineEditBox(const cocos2d::Rect &rect)
{
[[_sysEdit.textField cell] setLineBreakMode:NSLineBreakByTruncatingTail];
[[_sysEdit.textField cell] setTruncatesLastVisibleLine:YES];
[_sysEdit setPosition:NSMakePoint(rect.origin.x, rect.origin.y)];
[_sysEdit setContentSize:NSMakeSize(rect.size.width, rect.size.height)];
show();
}
void PlayerEditBoxServiceMac::showMultiLineEditBox(const cocos2d::Rect &rect)
{
[[_sysEdit.textField cell] setLineBreakMode:NSLineBreakByCharWrapping];
[[_sysEdit.textField cell] setTruncatesLastVisibleLine:NO];
[_sysEdit setPosition:NSMakePoint(rect.origin.x, rect.origin.y)];
[_sysEdit setContentSize:NSMakeSize(rect.size.width, rect.size.height)];
show();
}
void PlayerEditBoxServiceMac::setText(const std::string &text)
{
_sysEdit.textField.stringValue = [NSString stringWithUTF8String:text.c_str()];
}
void PlayerEditBoxServiceMac::setFont(const std::string &name, int size)
{
NSString *fntName = [NSString stringWithUTF8String:name.c_str()];
NSFont *textFont = [NSFont fontWithName:fntName size:size];
if (textFont != nil)
{
[_sysEdit.textField setFont:textFont];
}
}
void PlayerEditBoxServiceMac::setFontColor(const cocos2d::Color3B &color)
{
NSColor *textColor = [NSColor colorWithCalibratedRed:color.r / 255.0f green:color.g / 255.0f blue:color.b / 255.0f alpha:1.0f];
_sysEdit.textField.textColor = textColor;
}
// hide editbox
void PlayerEditBoxServiceMac::hide()
{
[_sysEdit.textField setHidden:YES];
[_sysEdit closeKeyboard];
}
void PlayerEditBoxServiceMac::show()
{
[_sysEdit.textField setHidden:NO];
[_sysEdit openKeyboard];
}
void PlayerEditBoxServiceMac::setFormator(int formator)
{
CCLOG("Not support yet.");
}
PLAYER_NS_END;

View File

@ -0,0 +1,50 @@
#ifndef __PLAY_FILE_DIALOG_SERVICE_MAC_H
#define __PLAY_FILE_DIALOG_SERVICE_MAC_H
#include "PlayerMacros.h"
#include "PlayerFileDialogServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerFileDialogServiceMac : public PlayerFileDialogServiceProtocol
{
public:
// 选择一个已有的文件,并返回文件的完整路径
// 如果用户取消对话框,返回空字符串
//
// @param title 对话框标题
// @param directory 默认打开的目录
//
// 如果 directory 不为空,则对话框打开时,直接进入 directory 参数指定的目录;
// 否则进入进程当前目录Current Directory
//
// @param extensions 用于限制可以打开的文件类型
//
// extensions 示例:
// extensions = "Lua Script File|*.lua;JSON File|*.json";
//
// 每一种类型分为“描述”和“扩展名”两部分,用“|”分隔
// 扩展名如果有多个,则用“,”分隔
// 不同类型用“;”分隔
//
// 如果 extensions 参数为空,则表示可以选择任何扩展名的文件。
//
virtual std::string openFile(const std::string &title,
const std::string &directory,
const std::string &extensions) const;
virtual std::vector<std::string> openMultiple(const std::string &title,
const std::string &directory,
const std::string &extensions) const;
virtual std::string saveFile(const std::string &title,
const std::string &path) const;
virtual std::string openDirectory(const std::string &title,
const std::string &directory)const;
};
PLAYER_NS_END
#endif // __PLAY_FILE_DIALOG_SERVICE_MAC_H

View File

@ -0,0 +1,174 @@
#include "PlayerFileDialogServiceMac.h"
#include "glfw3.h"
#include "glfw3native.h"
#define VALIDATE_FRAMEBUFFER { \
NSOpenGLContext *__context = glfwGetNSGLContext(glfwGetCurrentContext()); \
[__context makeCurrentContext]; \
}
PLAYER_NS_BEGIN
std::string PlayerFileDialogServiceMac::openFile(const std::string &title,
const std::string &directory,
const std::string &extensions) const
{
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setTitle:[NSString stringWithUTF8String:title.c_str()]];
[openDlg setCanChooseDirectories:NO];
[openDlg setCanChooseFiles:YES];
[openDlg setCanHide:YES];
[openDlg setCanCreateDirectories:NO];
[openDlg setCanSelectHiddenExtension:NO];
[openDlg setAllowsMultipleSelection:NO];
if (directory.length()) {
[openDlg setDirectoryURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:directory.c_str()]]];
}
if (extensions.length())
{
NSMutableArray *fileTypes = [NSMutableArray array];
NSString *buff = [NSString stringWithUTF8String:extensions.c_str()];
NSArray *extensionArray = [buff componentsSeparatedByString:@";"];
for (NSString *oneExtension in extensionArray) {
NSArray *tmpData = [oneExtension componentsSeparatedByString:@"|"];
if ([tmpData count] > 1)
{
NSString *suffixString = [tmpData objectAtIndex:1];
suffixString = [suffixString stringByReplacingOccurrencesOfString:@"*." withString:@""];
[fileTypes addObjectsFromArray:[suffixString componentsSeparatedByString:@","]];
}
}
[openDlg setAllowedFileTypes:fileTypes];
}
std::string filePath;
if ([openDlg runModal] == NSFileHandlingPanelOKButton)
{
NSURL *url = [openDlg.URLs objectAtIndex:0];
filePath = [[url path] UTF8String];
}
[openDlg close];
VALIDATE_FRAMEBUFFER
return filePath;
}
std::string PlayerFileDialogServiceMac::openDirectory( const std::string &title,
const std::string &directory) const
{
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setTitle:[NSString stringWithUTF8String:title.c_str()]];
[openDlg setCanChooseDirectories:YES];
[openDlg setCanChooseFiles:NO];
[openDlg setCanHide:YES];
[openDlg setCanCreateDirectories:NO];
[openDlg setCanSelectHiddenExtension:NO];
[openDlg setAllowsMultipleSelection:NO];
if (directory.length()) {
[openDlg setDirectoryURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:directory.c_str()]]];
}
std::string path;
if ([openDlg runModal] == NSFileHandlingPanelOKButton)
{
NSURL *url = [openDlg.URLs objectAtIndex:0];
path = [[url path] UTF8String];
}
[openDlg close];
VALIDATE_FRAMEBUFFER
return path;
}
std::vector<std::string> PlayerFileDialogServiceMac::openMultiple( const std::string &title,
const std::string &directory,
const std::string &extensions) const
{
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setTitle:[NSString stringWithUTF8String:title.c_str()]];
[openDlg setCanChooseDirectories:YES];
[openDlg setCanChooseFiles:YES];
[openDlg setCanHide:YES];
[openDlg setCanCreateDirectories:NO];
[openDlg setCanSelectHiddenExtension:NO];
[openDlg setAllowsMultipleSelection:YES];
if (directory.length()) {
[openDlg setDirectoryURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:directory.c_str()]]];
}
if (extensions.length())
{
NSMutableArray *fileTypes = [NSMutableArray array];
NSString *buff = [NSString stringWithUTF8String:extensions.c_str()];
NSArray *extensionArray = [buff componentsSeparatedByString:@";"];
for (NSString *oneExtension in extensionArray) {
NSArray *tmpData = [oneExtension componentsSeparatedByString:@"|"];
if ([tmpData count] > 1)
{
NSString *suffixString = [tmpData objectAtIndex:1];
suffixString = [suffixString stringByReplacingOccurrencesOfString:@"*." withString:@""];
[fileTypes addObjectsFromArray:[suffixString componentsSeparatedByString:@","]];
}
}
[openDlg setAllowedFileTypes:fileTypes];
}
std::vector<std::string> pathes;
if ([openDlg runModal] == NSFileHandlingPanelOKButton)
{
for (NSURL *url in openDlg.URLs) {
pathes.push_back([[url path] UTF8String]);
}
}
[openDlg close];
VALIDATE_FRAMEBUFFER
return pathes;
}
std::string PlayerFileDialogServiceMac::saveFile(const std::string &title,
const std::string &path) const
{
NSSavePanel* saveDlg = [NSSavePanel savePanel];
[saveDlg setTitle:[NSString stringWithUTF8String:title.c_str()]];
[saveDlg setCanHide:YES];
[saveDlg setCanCreateDirectories:NO];
[saveDlg setCanSelectHiddenExtension:NO];
// set directory
NSString *tempPath = [NSString stringWithUTF8String:path.c_str()];
NSString *directory = [tempPath stringByDeletingLastPathComponent];
if (directory)
{
[saveDlg setDirectoryURL:[NSURL fileURLWithPath:directory]];
}
// set filename
[saveDlg setNameFieldStringValue:[tempPath lastPathComponent]];
std::string filePath;
if ([saveDlg runModal] == NSFileHandlingPanelOKButton)
{
NSURL *url = saveDlg.URL;
filePath = [[url path] UTF8String];
}
[saveDlg close];
VALIDATE_FRAMEBUFFER
return filePath;
}
PLAYER_NS_END

View File

@ -0,0 +1,52 @@
#ifndef __PLAYER_MAC_H_
#define __PLAYER_MAC_H_
#include "PlayerProtocol.h"
#include "PlayerEditBoxServiceMac.h"
#include "PlayerFileDialogServiceMac.h"
#include "PlayerMenuServiceMac.h"
#include "PlayerMessageBoxServiceMac.h"
#include "PlayerTaskServiceMac.h"
#include "PlayerUtils.h"
#include "ProjectConfig/ProjectConfig.h"
PLAYER_NS_BEGIN
class PlayerMac : public PlayerProtocol
{
public:
static PlayerMac *create();
virtual ~PlayerMac();
virtual PlayerFileDialogServiceProtocol *getFileDialogService();
virtual PlayerMessageBoxServiceProtocol *getMessageBoxService();
virtual PlayerMenuServiceProtocol *getMenuService();
virtual PlayerEditBoxServiceProtocol *getEditBoxService();
virtual PlayerTaskServiceProtocol *getTaskService();
void quit();
void relaunch();
void openNewPlayer();
void openNewPlayerWithProjectConfig(const ProjectConfig& config);
void openProjectWithProjectConfig(const ProjectConfig& config);
void setController(id controller);
int getPositionX();
int getPositionY();
protected:
PlayerMac();
PlayerMenuServiceMac *_menuService;
PlayerMessageBoxServiceMac *_messageBoxService;
PlayerFileDialogServiceMac *_fileDialogService;
PlayerEditBoxServiceMac *_editBoxService;
PlayerTaskServiceMac *_taskService;
id _appController;
};
PLAYER_NS_END
#endif // __PLAYER_MAC_H_

View File

@ -0,0 +1,135 @@
#include "PlayerMac.h"
PLAYER_NS_BEGIN
using namespace cocos2d;
PlayerMac* PlayerMac::create()
{
return new PlayerMac();
}
PlayerMac::PlayerMac()
: PlayerProtocol()
, _fileDialogService(nullptr)
, _messageBoxService(nullptr)
, _menuService(nullptr)
, _editBoxService(nullptr)
, _appController(nullptr)
, _taskService(nullptr)
{
}
PlayerMac::~PlayerMac()
{
CC_SAFE_DELETE(_fileDialogService);
CC_SAFE_DELETE(_fileDialogService);
CC_SAFE_DELETE(_messageBoxService);
CC_SAFE_DELETE(_menuService);
CC_SAFE_DELETE(_editBoxService);
CC_SAFE_DELETE(_taskService);
}
PlayerFileDialogServiceProtocol *PlayerMac::getFileDialogService()
{
if (!_fileDialogService)
{
_fileDialogService = new PlayerFileDialogServiceMac();
}
return _fileDialogService;
}
PlayerMessageBoxServiceProtocol *PlayerMac::getMessageBoxService()
{
if (!_messageBoxService)
{
_messageBoxService = new PlayerMessageBoxServiceMac();
}
return _messageBoxService;
}
PlayerMenuServiceProtocol *PlayerMac::getMenuService()
{
if (!_menuService)
{
_menuService = new PlayerMenuServiceMac();
}
return _menuService;
}
PlayerEditBoxServiceProtocol *PlayerMac::getEditBoxService()
{
if (!_editBoxService)
{
_editBoxService = new PlayerEditBoxServiceMac();
}
return _editBoxService;
}
PlayerTaskServiceProtocol *PlayerMac::getTaskService()
{
if (!_taskService)
{
_taskService = new PlayerTaskServiceMac();
}
return _taskService;
}
void PlayerMac::quit()
{
cocos2d::Director::getInstance()->end();
}
void PlayerMac::relaunch()
{
if (_appController && [_appController respondsToSelector:NSSelectorFromString(@"relaunch")])
{
[_appController performSelector:NSSelectorFromString(@"relaunch")];
}
}
void PlayerMac::openNewPlayer()
{
}
void PlayerMac::openNewPlayerWithProjectConfig(const ProjectConfig& config)
{
if (_appController && [_appController respondsToSelector:NSSelectorFromString(@"launch:")])
{
NSString *commandLine = [NSString stringWithCString:config.makeCommandLine().c_str()
encoding:NSUTF8StringEncoding];
NSArray *arguments = [NSMutableArray arrayWithArray:[commandLine componentsSeparatedByString:@" "]];
[_appController performSelector:NSSelectorFromString(@"launch:") withObject:arguments];
}
}
void PlayerMac::openProjectWithProjectConfig(const ProjectConfig& config)
{
this->openNewPlayerWithProjectConfig(config);
this->quit();
}
void PlayerMac::setController(id controller)
{
_appController = controller;
}
int PlayerMac::getPositionX()
{
NSWindow *window = dynamic_cast<GLViewImpl*>(Director::getInstance()->getOpenGLView())->getCocoaWindow();
return window.frame.origin.x;
}
int PlayerMac::getPositionY()
{
NSWindow *window = dynamic_cast<GLViewImpl*>(Director::getInstance()->getOpenGLView())->getCocoaWindow();
return window.frame.origin.y;
}
PLAYER_NS_END

View File

@ -0,0 +1,78 @@
#ifndef __PLAYER_MENU_SERVICE_MAC_H_
#define __PLAYER_MENU_SERVICE_MAC_H_
#include <unordered_map>
#include "cocos2d.h"
#include "PlayerMacros.h"
#include "PlayerMenuServiceProtocol.h"
//
// Menu item Helper
//
PLAYER_NS_BEGIN
class PlayerMenuItemMac;
PLAYER_NS_END
@interface NNMenuItem : NSMenuItem <NSMenuDelegate>
@property (nonatomic) int scriptHandler;
@property (nonatomic) const player::PlayerMenuItemMac *macMenuItem;
+(id) createMenuItem:(const player::PlayerMenuItemMac *) macMenuItem;
@end
//
// PlayerMenuItemMac
//
PLAYER_NS_BEGIN
class PlayerMenuItemMac : public PlayerMenuItem
{
public:
static PlayerMenuItemMac *create(const std::string &menuId, const std::string &title);
virtual ~PlayerMenuItemMac();
virtual void setTitle(const std::string &title);
virtual void setEnabled(bool enabled);
virtual void setChecked(bool checked);
virtual void setShortcut(const std::string &shortcut);
protected:
PlayerMenuItemMac();
PlayerMenuItemMac *_parent;
NNMenuItem *_menuItem;
NSMenu *_menu;
cocos2d::Vector<PlayerMenuItemMac*> _children;
friend class PlayerMenuServiceMac;
};
class PlayerMenuServiceMac : public PlayerMenuServiceProtocol
{
public:
PlayerMenuServiceMac();
virtual ~PlayerMenuServiceMac();
virtual PlayerMenuItem *addItem(const std::string &menuId, const std::string &title, const std::string &parentId, int order = MAX_ORDER);
virtual PlayerMenuItem *addItem(const std::string &menuId, const std::string &title);
virtual PlayerMenuItem *getItem(const std::string &menuId);
virtual bool removeItem(const std::string &menuId);
virtual void setMenuBarEnabled(bool enabled);
private:
bool removeItemInternal(const std::string &menuId, bool isUpdateChildrenOrder);
void updateChildrenOrder(PlayerMenuItemMac *parent);
private:
PlayerMenuItemMac _root;
std::unordered_map<std::string, PlayerMenuItemMac*> _items;
};
PLAYER_NS_END
#endif // __PLAYER_MENU_SERVICE_MAC_H_

View File

@ -0,0 +1,370 @@
#include "PlayerMenuServiceMac.h"
#include "PlayerUtils.h"
#include "CCLuaEngine.h"
#include "cocos2d.h"
#include "AppEvent.h"
USING_NS_CC;
/////////////////////////////////////// menu helper //////////////////////////////////////////////
static bool __G_IS_MENUBAR_ENABLED__ = true; // WTF
@implementation NNMenuItem
+(id) createMenuItem:(const player::PlayerMenuItemMac *) macMenuItem
{
if (macMenuItem->getTitle().compare("-") == 0)
{
return [NSMenuItem separatorItem];
}
else
{
return [[[NNMenuItem alloc] initWithMenuItem:macMenuItem] autorelease];
}
return NULL;
}
-(id) initWithMenuItem:(const player::PlayerMenuItemMac *) menuItem
{
NSString *title = [NSString stringWithUTF8String:menuItem->getTitle().c_str()];
title = [title stringByReplacingOccurrencesOfString:@"&" withString:@""];
if ([super initWithTitle:title action:@selector(onClicked:) keyEquivalent:@""])
{
self.target = self;
}
self.macMenuItem = menuItem;
return self;
}
-(void) setShortcut:(std::string) shortcut
{
std::vector <std::string> fields = player::splitString(shortcut, std::string("+"));
NSUInteger mask = [self keyEquivalentModifierMask];
for (auto cut : fields)
{
if (cut == kPlayerSuperModifyKey)
{
mask |= NSCommandKeyMask;
}
else if (cut == kPlayerShiftModifyKey)
{
mask |= NSShiftKeyMask;
}
else if (cut == kPlayerCtrlModifyKey)
{
mask |= NSControlKeyMask;
}
else if (cut == kPlayerAltModifyKey)
{
mask |= NSAlternateKeyMask;
}
else
{
if (cut.length() == 1)
{
[self setKeyEquivalent:[NSString stringWithUTF8String:cut.c_str()]];
}
else
{
CCLOG("[modifyItem] shortcut (%s) is invalid.", shortcut.c_str());
}
}
}
if (mask != 0)
{
[self setKeyEquivalentModifierMask:mask];
}
}
-(void) onClicked:(id)sender
{
AppEvent event(kAppEventName, APP_EVENT_MENU);
std::stringstream buf;
buf << "{\"data\":\"" << self.macMenuItem->getMenuId().c_str() << "\"";
buf << ",\"name\":" << "\"menuClicked\"" << "}";
event.setDataString(buf.str());
event.setUserData((void*)self.macMenuItem);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
-(BOOL) validateMenuItem:(NSMenuItem *)menuItem
{
return __G_IS_MENUBAR_ENABLED__;
}
@end
PLAYER_NS_BEGIN
//
PlayerMenuItemMac *PlayerMenuItemMac::create(const std::string &menuId, const std::string &title)
{
PlayerMenuItemMac *item = new PlayerMenuItemMac();
item->_menuId = menuId;
item->_title = title;
item->autorelease();
return item;
}
PlayerMenuItemMac::PlayerMenuItemMac()
: _parent(nullptr)
, _menuItem(nullptr)
, _menu(nullptr)
{
}
PlayerMenuItemMac::~PlayerMenuItemMac()
{
CC_SAFE_RELEASE(_parent);
if (_menuItem)
{
[_parent->_menu removeItem:_menuItem];
}
CCLOG("PlayerMenuItemWin::~PlayerMenuItemWin() - %s", _menuId.c_str());
}
void PlayerMenuItemMac::setTitle(const std::string &title)
{
if (title.length() == 0)
{
CCLOG("MenuServiceWin::setTitle() - can not set menu title to empty, menu id (%s)", _menuId.c_str());
return;
}
_menuItem.title = [NSString stringWithUTF8String:title.c_str()];
if (_menu)
{
_menu.title = _menuItem.title;
}
_title = title;
}
void PlayerMenuItemMac::setEnabled(bool enabled)
{
_isEnabled = enabled;
if (enabled)
{
[_menuItem setAction:@selector(onClicked:)];
}
else
{
[_menuItem setAction:nil];
}
}
void PlayerMenuItemMac::setChecked(bool checked)
{
_isChecked = checked;
[_menuItem setState:checked ? NSOnState : NSOffState];
}
void PlayerMenuItemMac::setShortcut(const std::string &shortcut)
{
_shortcut = shortcut;
[_menuItem setShortcut:shortcut];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
PlayerMenuServiceMac::PlayerMenuServiceMac()
{
// @TODO: build menu with **EDIT** menu
NSApplication *thisApp = [NSApplication sharedApplication];
_root._menu = [thisApp mainMenu];
}
PlayerMenuServiceMac::~PlayerMenuServiceMac()
{
log("~PlayerMenuServiceMac");
_items.clear();
}
PlayerMenuItem* PlayerMenuServiceMac::addItem(const std::string &menuId, const std::string &title,
const std::string &parentId, int order)
{
if (menuId.length() == 0 || title.length() == 0)
{
CCLOG("PlayerMenuServiceMac::addItem() - menuId and title must is non-empty");
return nullptr;
}
// check menu id is exists
if (_items.find(menuId) != _items.end())
{
CCLOG("PlayerMenuServiceMac::addItem() - menu id (%s) is exists", menuId.c_str());
return nullptr;
}
// set parent
PlayerMenuItemMac *parent = &_root;
if (parentId.length())
{
// query parent menu
auto it = _items.find(parentId);
if (it != _items.end())
{
parent = it->second;
}
}
if (!parent->_menu)
{
NSMenu *nsmenu = [[NSMenu alloc] initWithTitle:[parent->_menuItem title]];
[parent->_parent->_menu setSubmenu:nsmenu forItem:parent->_menuItem];
parent->_menu = nsmenu;
parent->_isGroup = true;
}
// create new menu item
PlayerMenuItemMac *item = PlayerMenuItemMac::create(menuId, title);
item->_parent = parent;
item->_parent->retain();
// check new menu item position
int childSize = (int) [parent->_menu itemArray].count;
childSize = (int) parent->_children.size();
if (order > childSize)
{
order = childSize;
}
else if (order < 0)
{
order = 0;
}
// add menu item to menu bar
int newIndex = order;
if (parent == &_root)
{
newIndex += 1;
}
NNMenuItem *newItem = [NNMenuItem createMenuItem:item];
[parent->_menu insertItem:newItem atIndex:newIndex];
item->_menuItem = newItem;
// update menu state
parent->_children.insert(order, item);
_items[item->_menuId] = item;
updateChildrenOrder(parent);
return item;
}
PlayerMenuItem* PlayerMenuServiceMac::addItem(const std::string &menuId, const std::string &title)
{
return addItem(menuId, title, "");
}
PlayerMenuItem* PlayerMenuServiceMac::getItem(const std::string &menuId)
{
auto it = _items.find(menuId);
if (it == _items.end())
{
CCLOG("MenuServiceWin::getItem() - Invalid menu id (%s)", menuId.c_str());
return nullptr;
}
return it->second;
}
bool PlayerMenuServiceMac::removeItem(const std::string &menuId)
{
return removeItemInternal(menuId, true);;
}
void PlayerMenuServiceMac::setMenuBarEnabled(bool enabled)
{
__G_IS_MENUBAR_ENABLED__ = enabled;
}
#pragma mark - private -
bool PlayerMenuServiceMac::removeItemInternal(const std::string &menuId, bool isUpdateChildrenOrder)
{
auto it = _items.find(menuId);
if (it == _items.end())
{
CCLOG("MenuServiceWin::removeItem() - Invalid menu id (%s)", menuId.c_str());
return false;
}
PlayerMenuItemMac *item = it->second;
if (item->_children.size() == 0)
{
// remove item from parent
bool removed = false;
auto *theChildren = &item->_parent->_children;
for (auto it = theChildren->begin(); it != theChildren->end(); ++it)
{
if ((*it)->_menuItem == item->_menuItem)
{
theChildren->erase(it);
removed = true;
break;
}
}
if (!removed)
{
CCLOG("MenuServiceWin::removeItem() - remove menu item (%s) failed, not found command id from parent->children", item->_menuId.c_str());
}
// remove menu id mapping
_items.erase(menuId);
if (isUpdateChildrenOrder)
{
updateChildrenOrder(item->_parent);
}
return true;
}
else
{
// remove all children
while (item->_children.size() != 0)
{
PlayerMenuItemMac *child = *item->_children.begin();
if (!removeItemInternal(child->_menuId.c_str(), false))
{
break;
return false;
}
}
return removeItemInternal(menuId, true);
}
return false;
}
void PlayerMenuServiceMac::updateChildrenOrder(PlayerMenuItemMac *parent)
{
auto *children = &parent->_children;
int order = 0;
for (auto it = children->begin(); it != children->end(); ++it)
{
(*it)->_order = order;
order++;
}
}
PLAYER_NS_END

View File

@ -0,0 +1,29 @@
#ifndef __PLAYER_MessageBoxServiceMac_h
#define __PLAYER_MessageBoxServiceMac_h
#include <vector>
#include "PlayerMacros.h"
#include "PlayerMessageBoxServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerMessageBoxServiceMac : public PlayerMessageBoxServiceProtocol
{
public:
virtual int showMessageBox(const std::string &title,
const std::string &message,
int buttonsType = BUTTONS_OK);
protected:
struct MessageBoxInfo
{
std::string title;
const int buttonId;
};
std::vector<MessageBoxInfo> getTitles(int buttons);
};
PLAYER_NS_END
#endif // __PLAYER_MessageBoxServiceMac_h

View File

@ -0,0 +1,58 @@
#include "PlayerMessageBoxServiceMac.h"
PLAYER_NS_BEGIN
int PlayerMessageBoxServiceMac::showMessageBox(const std::string &title,
const std::string &message,
int buttonsType)
{
NSAlert *alert = [[NSAlert alloc] init];
auto titles = getTitles(buttonsType);
for (auto& title : titles)
{
[alert addButtonWithTitle:[NSString stringWithUTF8String:title.title.c_str()]];
}
[alert setMessageText:[NSString stringWithUTF8String:title.c_str()]];
[alert setInformativeText:[NSString stringWithUTF8String:message.c_str()]];
[alert setAlertStyle:NSWarningAlertStyle];
int index = (int)[alert runModal] - NSAlertFirstButtonReturn;
return titles.at(index).buttonId;
}
std::vector<PlayerMessageBoxServiceMac::MessageBoxInfo> PlayerMessageBoxServiceMac::getTitles(int buttons)
{
std::vector<PlayerMessageBoxServiceMac::MessageBoxInfo> titles;
switch (buttons) {
case BUTTONS_OK:
titles.push_back({"OK", BUTTON_OK});
break;
case BUTTONS_OK_CANCEL:
titles.push_back({"OK", BUTTON_OK});
titles.push_back({"Cancel", BUTTON_CANCEL});
break;
case BUTTONS_YES_NO:
titles.push_back({"Yes", BUTTON_YES});
titles.push_back({"No", BUTTON_NO});
break;
case BUTTONS_YES_NO_CANCEL:
titles.push_back({"Yes", BUTTON_YES});
titles.push_back({"No", BUTTON_NO});
titles.push_back({"Cancel", BUTTON_CANCEL});
break;
default:
break;
}
return titles;
}
PLAYER_NS_END

View File

@ -0,0 +1,75 @@
#ifndef __PLAYER_TASK_SERVICE_MAC_H_
#define __PLAYER_TASK_SERVICE_MAC_H_
#include <sstream>
#include "PlayerTaskServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerTaskMac;
PLAYER_NS_END
@interface PlayerTaskPrivate : NSObject
{
NSFileHandle *fileHandle;
}
@property (assign) NSTask *buildTask;
@property (assign) BOOL isRunning;
@property (assign) int exitCode;
@property (retain) NSString *output;
- (void) runScriptAsyn:(NSString *)absScriptPath withArguments:(NSArray *) arguments;
@end
PLAYER_NS_BEGIN
class PlayerTaskMac : public PlayerTask
{
public:
static PlayerTaskMac *create(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments);
virtual ~PlayerTaskMac();
virtual bool run();
virtual void stop();
virtual void runInTerminal();
// check task status
virtual void update(float dt);
void appendOutput(const char *data);
protected:
PlayerTaskMac(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments);
void cleanup();
std::u16string makeCommandLine() const;
PlayerTaskPrivate *_taskPrivate;
};
class PlayerTaskServiceMac : public PlayerTaskServiceProtocol
{
public:
PlayerTaskServiceMac();
virtual ~PlayerTaskServiceMac();
virtual PlayerTask *createTask(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments);
virtual PlayerTask *getTask(const std::string &name);
virtual void removeTask(const std::string &name);
protected:
cocos2d::Map<std::string, PlayerTaskMac*> _tasks;
};
PLAYER_NS_END
#endif // __PLAYER_TASK_SERVICE_MAC_H_

View File

@ -0,0 +1,241 @@
#include "PlayerTaskServiceMac.h"
@implementation PlayerTaskPrivate
-(id) init
{
if ((self = [super init])) {
_isRunning = NO;
_exitCode = 0;
}
return self;
}
-(void) dealloc
{
[_output release];
[super dealloc];
}
-(void)performSelectorInBackground:(SEL)selector withObjects:(id)object, ...
{
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
// setup the invocation
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.target = self;
invocation.selector = selector;
// associate the arguments
va_list objects;
va_start(objects, object);
unsigned int objectCounter = 2;
for (id obj = object; obj != nil; obj = va_arg(objects, id))
{
[invocation setArgument:&obj atIndex:objectCounter++];
}
va_end(objects);
// make sure to invoke on a background queue
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithInvocation:invocation];
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
[backgroundQueue addOperation:operation];
}
- (void) runScriptAsyn:(NSString *)absScriptPath withArguments:(NSArray *) arguments
{
_isRunning = YES;
[self performSelectorInBackground:@selector(runScriptSync:withArguments:)
withObjects:absScriptPath, arguments, nil];
}
- (void) runScriptSync:(NSString *)absScriptPath withArguments:(NSArray *)arguments
{
if (!absScriptPath)
{
CCLOG("Please check your script (%s)", absScriptPath.UTF8String);
return ;
}
_buildTask = [[NSTask alloc] init];
[_buildTask setLaunchPath:absScriptPath];
if (!arguments)
{
arguments = [NSArray array];
}
[_buildTask setArguments:arguments];
//
NSPipe *pipe;
pipe = [NSPipe pipe];
[_buildTask setStandardOutput: pipe];
fileHandle = [pipe fileHandleForReading];
//
[_buildTask launch];
[_buildTask waitUntilExit];
NSData *data;
data = [fileHandle readDataToEndOfFile];
_output = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
_isRunning = NO;
_exitCode = [_buildTask terminationStatus];
[fileHandle closeFile];
[_buildTask release];
_buildTask = nil;
}
@end
PLAYER_NS_BEGIN
PlayerTaskMac *PlayerTaskMac::create(const std::string &name, const std::string &executePath, const std::string &commandLineArguments)
{
PlayerTaskMac *task = new PlayerTaskMac(name, executePath, commandLineArguments);
task->autorelease();
return task;
}
PlayerTaskMac::PlayerTaskMac(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments)
: PlayerTask(name, executePath, commandLineArguments)
{
_taskPrivate = [[PlayerTaskPrivate alloc] init];
}
PlayerTaskMac::~PlayerTaskMac()
{
cleanup();
}
bool PlayerTaskMac::run()
{
if (!isIdle())
{
CCLOG("PlayerTaskMac::run() - task is not idle");
return false;
}
NSString *commandLine = [NSString stringWithCString:_commandLineArguments.c_str()
encoding:NSUTF8StringEncoding];
[_taskPrivate runScriptAsyn:[NSString stringWithUTF8String:_executePath.data()]
withArguments:[NSMutableArray arrayWithArray:[commandLine componentsSeparatedByString:@" "]]];
_state = STATE_RUNNING;
cocos2d::Director::getInstance()->getScheduler()->scheduleUpdate(this, 0, false);
return true;
}
void PlayerTaskMac::runInTerminal()
{
NSString *s = [NSString stringWithFormat:
@"tell application \"Terminal\" to do script \"%s %s\"", _executePath.c_str(), _commandLineArguments.c_str()];
NSAppleScript *as = [[NSAppleScript alloc] initWithSource: s];
[as executeAndReturnError:nil];
}
void PlayerTaskMac::stop()
{
cleanup();
}
void PlayerTaskMac::update(float dt)
{
_lifetime += dt;
if (_taskPrivate.isRunning)
{
return ;
}
cocos2d::Director::getInstance()->getScheduler()->unscheduleAllForTarget(this);
cleanup();
}
void PlayerTaskMac::appendOutput(const char *data)
{
_output.append(data);
}
void PlayerTaskMac::cleanup()
{
_state = STATE_COMPLETED;
[NSObject cancelPreviousPerformRequestsWithTarget:_taskPrivate];
[_taskPrivate.buildTask interrupt];
_resultCode = _taskPrivate.exitCode;
_output.append(_taskPrivate.output.UTF8String);
[_taskPrivate release];
_taskPrivate = nil;
CCLOG("\nCMD: (exit code: %d) %s", _resultCode, _output.c_str());
cocos2d::Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(_name);
}
std::u16string PlayerTaskMac::makeCommandLine() const
{
std::stringstream buf;
buf << "\"";
buf << _executePath;
buf << "\" ";
buf << _commandLineArguments;
std::u16string u16command;
cocos2d::StringUtils::UTF8ToUTF16(buf.str(), u16command);
return u16command;
}
PlayerTaskServiceMac::PlayerTaskServiceMac()
{
}
PlayerTaskServiceMac::~PlayerTaskServiceMac()
{
for (auto it = _tasks.begin(); it != _tasks.end(); ++it)
{
it->second->stop();
}
}
PlayerTask *PlayerTaskServiceMac::createTask(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments)
{
CCASSERT(_tasks.find(name) == _tasks.end(), "Task already exists.");
PlayerTaskMac *task = PlayerTaskMac::create(name, executePath, commandLineArguments);
_tasks.insert(name, task);
return task;
}
PlayerTask *PlayerTaskServiceMac::getTask(const std::string &name)
{
auto it = _tasks.find(name);
return it != _tasks.end() ? it->second : nullptr;
}
void PlayerTaskServiceMac::removeTask(const std::string &name)
{
auto it = _tasks.find(name);
if (it != _tasks.end())
{
if (!it->second->isCompleted())
{
it->second->stop();
}
_tasks.erase(it);
}
}
PLAYER_NS_END

View File

@ -0,0 +1,65 @@
//
// OpenUDID.h
// openudid
//
// initiated by Yann Lechelle (cofounder @Appsfire) on 8/28/11.
// Copyright 2011 OpenUDID.org
//
// Main branches
// iOS code: https://github.com/ylechelle/OpenUDID
//
/*
!!! IMPORTANT !!!
IF YOU ARE GOING TO INTEGRATE OpenUDID INSIDE A (STATIC) LIBRARY,
PLEASE MAKE SURE YOU REFACTOR THE OpenUDID CLASS WITH A PREFIX OF YOUR OWN,
E.G. ACME_OpenUDID. THIS WILL AVOID CONFUSION BY DEVELOPERS WHO ARE ALSO
USING OpenUDID IN THEIR OWN CODE.
!!! IMPORTANT !!!
*/
/*
http://en.wikipedia.org/wiki/Zlib_License
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#import <Foundation/Foundation.h>
//
// Usage:
// #include "OpenUDID.h"
// NSString* openUDID = [OpenUDID value];
//
#define kOpenUDIDErrorNone 0
#define kOpenUDIDErrorOptedOut 1
#define kOpenUDIDErrorCompromised 2
@interface OpenUDIDMac : NSObject {
}
+ (NSString*) value;
+ (NSString*) valueWithError:(NSError**)error;
+ (void) setOptOut:(BOOL)optOutValue;
@end

View File

@ -0,0 +1,383 @@
//
// OpenUDIDMac.m
// openudid
//
// initiated by Yann Lechelle (cofounder @Appsfire) on 8/28/11.
// Copyright 2011 OpenUDID.org
//
// Initiators/root branches
// iOS code: https://github.com/ylechelle/OpenUDID
// Android code: https://github.com/vieux/OpenUDID
//
// Contributors:
// https://github.com/ylechelle/OpenUDID/contributors
//
/*
http://en.wikipedia.org/wiki/Zlib_License
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#if __has_feature(objc_arc)
#error This file uses the classic non-ARC retain/release model; hints below...
// to selectively compile this file as non-ARC, do as follows:
// https://img.skitch.com/20120717-g3ag5h9a6ehkgpmpjiuen3qpwp.png
#endif
#import "OpenUDIDMac.h"
#import <CommonCrypto/CommonDigest.h> // Need to import for CC_MD5 access
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#import <UIKit/UIPasteboard.h>
#import <UIKit/UIKit.h>
#else
#import <AppKit/NSPasteboard.h>
#endif
#define OpenUDIDLog(fmt, ...)
//#define OpenUDIDLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
//#define OpenUDIDLog(fmt, ...) NSLog((@"[Line %d] " fmt), __LINE__, ##__VA_ARGS__);
static NSString * kOpenUDIDSessionCache = nil;
static NSString * const kOpenUDIDKey = @"OpenUDID";
static NSString * const kOpenUDIDSlotKey = @"OpenUDID_slot";
static NSString * const kOpenUDIDAppUIDKey = @"OpenUDID_appUID";
static NSString * const kOpenUDIDTSKey = @"OpenUDID_createdTS";
static NSString * const kOpenUDIDOOTSKey = @"OpenUDID_optOutTS";
static NSString * const kOpenUDIDDomain = @"org.OpenUDID";
static NSString * const kOpenUDIDSlotPBPrefix = @"org.OpenUDID.slot.";
static int const kOpenUDIDRedundancySlots = 100;
@interface OpenUDIDMac (Private)
+ (void) _setDict:(id)dict forPasteboard:(id)pboard;
+ (NSMutableDictionary*) _getDictFromPasteboard:(id)pboard;
+ (NSString*) _generateFreshOpenUDID;
@end
@implementation OpenUDIDMac
// Archive a NSDictionary inside a pasteboard of a given type
// Convenience method to support iOS & Mac OS X
//
+ (void) _setDict:(id)dict forPasteboard:(id)pboard {
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
[pboard setData:[NSKeyedArchiver archivedDataWithRootObject:dict] forPasteboardType:kOpenUDIDDomain];
#else
[pboard setData:[NSKeyedArchiver archivedDataWithRootObject:dict] forType:kOpenUDIDDomain];
#endif
}
// Retrieve an NSDictionary from a pasteboard of a given type
// Convenience method to support iOS & Mac OS X
//
+ (NSMutableDictionary*) _getDictFromPasteboard:(id)pboard {
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
id item = [pboard dataForPasteboardType:kOpenUDIDDomain];
#else
id item = [pboard dataForType:kOpenUDIDDomain];
#endif
if (item) {
@try{
item = [NSKeyedUnarchiver unarchiveObjectWithData:item];
} @catch(NSException* e) {
OpenUDIDLog(@"Unable to unarchive item %@ on pasteboard!", [pboard name]);
item = nil;
}
}
// return an instance of a MutableDictionary
return [NSMutableDictionary dictionaryWithDictionary:(item == nil || [item isKindOfClass:[NSDictionary class]]) ? item : nil];
}
// Private method to create and return a new OpenUDID
// Theoretically, this function is called once ever per application when calling [OpenUDID value] for the first time.
// After that, the caching/pasteboard/redundancy mechanism inside [OpenUDID value] returns a persistent and cross application OpenUDID
//
+ (NSString*) _generateFreshOpenUDID {
NSString* _openUDID = nil;
// August 2011: One day, this may no longer be allowed in iOS. When that is, just comment this line out.
// March 25th 2012: this day has come, let's remove this "outlawed" call...
#if TARGET_OS_IPHONE
// if([UIDevice instancesRespondToSelector:@selector(uniqueIdentifier)]){
// _openUDID = [[UIDevice currentDevice] uniqueIdentifier];
// }
#endif
// Next we generate a UUID.
// UUIDs (Universally Unique Identifiers), also known as GUIDs (Globally Unique Identifiers) or IIDs
// (Interface Identifiers), are 128-bit values guaranteed to be unique. A UUID is made unique over
// both space and time by combining a value unique to the computer on which it was generatedusually the
// Ethernet hardware addressand a value representing the number of 100-nanosecond intervals since
// October 15, 1582 at 00:00:00.
// We then hash this UUID with md5 to get 32 bytes, and then add 4 extra random bytes
// Collision is possible of course, but unlikely and suitable for most industry needs (e.g. aggregate tracking)
//
if (_openUDID==nil) {
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef cfstring = CFUUIDCreateString(kCFAllocatorDefault, uuid);
const char *cStr = CFStringGetCStringPtr(cfstring,CFStringGetFastestEncoding(cfstring));
unsigned char result[16];
CC_MD5( cStr, (unsigned int)strlen(cStr), result );
CFRelease(uuid);
_openUDID = [NSString stringWithFormat:
@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%08x",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15],
(unsigned int)(arc4random() % NSUIntegerMax)];
}
// Call to other developers in the Open Source community:
//
// feel free to suggest better or alternative "UDID" generation code above.
// NOTE that the goal is NOT to find a better hash method, but rather, find a decentralized (i.e. not web-based)
// 160 bits / 20 bytes random string generator with the fewest possible collisions.
//
return _openUDID;
}
// Main public method that returns the OpenUDID
// This method will generate and store the OpenUDID if it doesn't exist, typically the first time it is called
// It will return the null udid (forty zeros) if the user has somehow opted this app out (this is subject to 3rd party implementation)
// Otherwise, it will register the current app and return the OpenUDID
//
+ (NSString*) value {
return [OpenUDIDMac valueWithError:nil];
}
+ (NSString*) valueWithError:(NSError **)error {
if (kOpenUDIDSessionCache!=nil) {
if (error!=nil)
*error = [NSError errorWithDomain:kOpenUDIDDomain
code:kOpenUDIDErrorNone
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID in cache from first call",@"description", nil]];
return kOpenUDIDSessionCache;
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// The AppUID will uniquely identify this app within the pastebins
//
NSString * appUID = (NSString *) [defaults objectForKey:kOpenUDIDAppUIDKey];
if(appUID == nil)
{
// generate a new uuid and store it in user defaults
CFUUIDRef uuid = CFUUIDCreate(NULL);
appUID = (NSString *) CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
}
NSString* openUDID = nil;
NSString* myRedundancySlotPBid = nil;
NSDate* optedOutDate = nil;
BOOL optedOut = NO;
BOOL saveLocalDictToDefaults = NO;
BOOL isCompromised = NO;
// Do we have a local copy of the OpenUDID dictionary?
// This local copy contains a copy of the openUDID, myRedundancySlotPBid (and unused in this block, the local bundleid, and the timestamp)
//
id localDict = [defaults objectForKey:kOpenUDIDKey];
if ([localDict isKindOfClass:[NSDictionary class]]) {
localDict = [NSMutableDictionary dictionaryWithDictionary:localDict]; // we might need to set/overwrite the redundancy slot
openUDID = [localDict objectForKey:kOpenUDIDKey];
myRedundancySlotPBid = [localDict objectForKey:kOpenUDIDSlotKey];
optedOutDate = [localDict objectForKey:kOpenUDIDOOTSKey];
optedOut = optedOutDate!=nil;
OpenUDIDLog(@"localDict = %@",localDict);
}
// Here we go through a sequence of slots, each of which being a UIPasteboard created by each participating app
// The idea behind this is to both multiple and redundant representations of OpenUDIDs, as well as serve as placeholder for potential opt-out
//
NSString* availableSlotPBid = nil;
NSMutableDictionary* frequencyDict = [NSMutableDictionary dictionaryWithCapacity:kOpenUDIDRedundancySlots];
for (int n=0; n<kOpenUDIDRedundancySlots; n++) {
NSString* slotPBid = [NSString stringWithFormat:@"%@%d",kOpenUDIDSlotPBPrefix,n];
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
UIPasteboard* slotPB = [UIPasteboard pasteboardWithName:slotPBid create:NO];
#else
NSPasteboard* slotPB = [NSPasteboard pasteboardWithName:slotPBid];
#endif
OpenUDIDLog(@"SlotPB name = %@",slotPBid);
if (slotPB==nil) {
// assign availableSlotPBid to be the first one available
if (availableSlotPBid==nil) availableSlotPBid = slotPBid;
} else {
NSDictionary* dict = [OpenUDIDMac _getDictFromPasteboard:slotPB];
NSString* oudid = [dict objectForKey:kOpenUDIDKey];
OpenUDIDLog(@"SlotPB dict = %@",dict);
if (oudid==nil) {
// availableSlotPBid could inside a non null slot where no oudid can be found
if (availableSlotPBid==nil) availableSlotPBid = slotPBid;
} else {
// increment the frequency of this oudid key
int count = [[frequencyDict valueForKey:oudid] intValue];
[frequencyDict setObject:[NSNumber numberWithInt:++count] forKey:oudid];
}
// if we have a match with the app unique id,
// then let's look if the external UIPasteboard representation marks this app as OptedOut
NSString* gid = [dict objectForKey:kOpenUDIDAppUIDKey];
if (gid!=nil && [gid isEqualToString:appUID]) {
myRedundancySlotPBid = slotPBid;
// the local dictionary is prime on the opt-out subject, so ignore if already opted-out locally
if (optedOut) {
optedOutDate = [dict objectForKey:kOpenUDIDOOTSKey];
optedOut = optedOutDate!=nil;
}
}
}
}
// sort the Frequency dict with highest occurence count of the same OpenUDID (redundancy, failsafe)
// highest is last in the list
//
NSArray* arrayOfUDIDs = [frequencyDict keysSortedByValueUsingSelector:@selector(compare:)];
NSString* mostReliableOpenUDID = (arrayOfUDIDs!=nil && [arrayOfUDIDs count]>0)? [arrayOfUDIDs lastObject] : nil;
OpenUDIDLog(@"Freq Dict = %@\nMost reliable %@",frequencyDict,mostReliableOpenUDID);
// if openUDID was not retrieved from the local preferences, then let's try to get it from the frequency dictionary above
//
if (openUDID==nil) {
if (mostReliableOpenUDID==nil) {
// this is the case where this app instance is likely to be the first one to use OpenUDID on this device
// we create the OpenUDID, legacy or semi-random (i.e. most certainly unique)
//
openUDID = [OpenUDIDMac _generateFreshOpenUDID];
} else {
// or we leverage the OpenUDID shared by other apps that have already gone through the process
//
openUDID = mostReliableOpenUDID;
}
// then we create a local representation
//
if (localDict==nil) {
localDict = [NSMutableDictionary dictionaryWithCapacity:4];
[localDict setObject:openUDID forKey:kOpenUDIDKey];
[localDict setObject:appUID forKey:kOpenUDIDAppUIDKey];
[localDict setObject:[NSDate date] forKey:kOpenUDIDTSKey];
if (optedOut) [localDict setObject:optedOutDate forKey:kOpenUDIDTSKey];
saveLocalDictToDefaults = YES;
}
}
else {
// Sanity/tampering check
//
if (mostReliableOpenUDID!=nil && ![mostReliableOpenUDID isEqualToString:openUDID])
isCompromised = YES;
}
// Here we store in the available PB slot, if applicable
//
OpenUDIDLog(@"Available Slot %@ Existing Slot %@",availableSlotPBid,myRedundancySlotPBid);
if (availableSlotPBid!=nil && (myRedundancySlotPBid==nil || [availableSlotPBid isEqualToString:myRedundancySlotPBid])) {
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
UIPasteboard* slotPB = [UIPasteboard pasteboardWithName:availableSlotPBid create:YES];
[slotPB setPersistent:YES];
#else
NSPasteboard* slotPB = [NSPasteboard pasteboardWithName:availableSlotPBid];
#endif
// save slotPBid to the defaults, and remember to save later
//
if (localDict) {
[localDict setObject:availableSlotPBid forKey:kOpenUDIDSlotKey];
saveLocalDictToDefaults = YES;
}
// Save the local dictionary to the corresponding UIPasteboard slot
//
if (openUDID && localDict)
[OpenUDIDMac _setDict:localDict forPasteboard:slotPB];
}
// Save the dictionary locally if applicable
//
if (localDict && saveLocalDictToDefaults)
[defaults setObject:localDict forKey:kOpenUDIDKey];
// If the UIPasteboard external representation marks this app as opted-out, then to respect privacy, we return the ZERO OpenUDID, a sequence of 40 zeros...
// This is a *new* case that developers have to deal with. Unlikely, statistically low, but still.
// To circumvent this and maintain good tracking (conversion ratios, etc.), developers are invited to calculate how many of their users have opted-out from the full set of users.
// This ratio will let them extrapolate convertion ratios more accurately.
//
if (optedOut) {
if (error!=nil) *error = [NSError errorWithDomain:kOpenUDIDDomain
code:kOpenUDIDErrorOptedOut
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Application with unique id %@ is opted-out from OpenUDID as of %@",appUID,optedOutDate],@"description", nil]];
kOpenUDIDSessionCache = [[NSString stringWithFormat:@"%040x",0] retain];
return kOpenUDIDSessionCache;
}
// return the well earned openUDID!
//
if (error!=nil) {
if (isCompromised)
*error = [NSError errorWithDomain:kOpenUDIDDomain
code:kOpenUDIDErrorCompromised
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Found a discrepancy between stored OpenUDID (reliable) and redundant copies; one of the apps on the device is most likely corrupting the OpenUDID protocol",@"description", nil]];
else
*error = [NSError errorWithDomain:kOpenUDIDDomain
code:kOpenUDIDErrorNone
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID succesfully retrieved",@"description", nil]];
}
kOpenUDIDSessionCache = [openUDID retain];
return kOpenUDIDSessionCache;
}
+ (void) setOptOut:(BOOL)optOutValue {
// init call
[OpenUDIDMac value];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// load the dictionary from local cache or create one
id dict = [defaults objectForKey:kOpenUDIDKey];
if ([dict isKindOfClass:[NSDictionary class]]) {
dict = [NSMutableDictionary dictionaryWithDictionary:dict];
} else {
dict = [NSMutableDictionary dictionaryWithCapacity:2];
}
// set the opt-out date or remove key, according to parameter
if (optOutValue)
[dict setObject:[NSDate date] forKey:kOpenUDIDOOTSKey];
else
[dict removeObjectForKey:kOpenUDIDOOTSKey];
// store the dictionary locally
[defaults setObject:dict forKey:kOpenUDIDKey];
OpenUDIDLog(@"Local dict after opt-out = %@",dict);
// reset memory cache
kOpenUDIDSessionCache = nil;
}
@end

View File

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6254"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AppController">
<connections>
<outlet property="delegate" destination="536" id="537"/>
<outlet property="menu" destination="29" id="650"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<menu title="AMainMenu" systemMenu="main" id="29">
<items>
<menuItem title="模拟器" id="56">
<menu key="submenu" title="模拟器" systemMenu="apple" id="57">
<items>
<menuItem title="关于 模拟器" id="58">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="143">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="服务" id="131">
<menu key="submenu" title="服务" systemMenu="services" id="130"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="144">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="隐藏 模拟器" keyEquivalent="h" id="134">
<connections>
<action selector="hide:" target="-1" id="367"/>
</connections>
</menuItem>
<menuItem title="隐藏其他窗口" keyEquivalent="h" id="145">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="368"/>
</connections>
</menuItem>
<menuItem title="全部显示" id="150">
<connections>
<action selector="unhideAllApplications:" target="-1" id="370"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="149">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="退出 模拟器" keyEquivalent="q" id="136">
<connections>
<action selector="onFileClose:" target="-1" id="UyZ-bV-2zL"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="编辑" id="Sqe-GR-erP">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="编辑" id="k0V-hR-upN">
<items>
<menuItem title="Undo" keyEquivalent="z" id="Ueo-Yj-fzm">
<connections>
<action selector="undo:" target="-1" id="Ex2-6U-hZI"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="x6z-iQ-VK2">
<connections>
<action selector="redo:" target="-1" id="KEx-Aj-tYn"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="COi-E7-7M4"/>
<menuItem title="剪切" keyEquivalent="x" id="NAk-12-pg4">
<connections>
<action selector="cut:" target="-1" id="Owu-Ie-Kfg"/>
</connections>
</menuItem>
<menuItem title="拷贝" keyEquivalent="c" id="XOY-ya-lNt">
<connections>
<action selector="copy:" target="-1" id="aIB-pV-N2w"/>
</connections>
</menuItem>
<menuItem title="粘贴" keyEquivalent="v" id="ul0-51-Ibd">
<connections>
<action selector="paste:" target="-1" id="7rk-Tb-7hI"/>
</connections>
</menuItem>
<menuItem title="粘贴并匹配样式" keyEquivalent="V" id="Zvy-7g-x4q">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="-1" id="oM4-kj-hTQ"/>
</connections>
</menuItem>
<menuItem title="删除" id="Xyz-QC-wlG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="-1" id="idJ-aN-6bB"/>
</connections>
</menuItem>
<menuItem title="选择全部" keyEquivalent="a" id="4fT-JL-N6e">
<connections>
<action selector="selectAll:" target="-1" id="pAH-rW-PaD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="osB-R6-2jE"/>
<menuItem title="查找" id="bms-8x-7Yb">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="查找" id="AXr-4L-lcV">
<items>
<menuItem title="查找" tag="1" keyEquivalent="f" id="GS8-y9-yQY">
<connections>
<action selector="performFindPanelAction:" target="-1" id="jVT-dG-Frl"/>
</connections>
</menuItem>
<menuItem title="查找下一个" tag="2" keyEquivalent="g" id="RJc-P7-Ibq">
<connections>
<action selector="performFindPanelAction:" target="-1" id="yLp-2a-Nuk"/>
</connections>
</menuItem>
<menuItem title="查找上一个" tag="3" keyEquivalent="G" id="f5k-Su-hK0">
<connections>
<action selector="performFindPanelAction:" target="-1" id="uoF-9Z-ef7"/>
</connections>
</menuItem>
<menuItem title="使用查找选择" tag="7" keyEquivalent="e" id="9Zj-Be-aBN">
<connections>
<action selector="performFindPanelAction:" target="-1" id="8hs-AK-0U8"/>
</connections>
</menuItem>
<menuItem title="跳转到选择" keyEquivalent="j" id="4tD-ef-pd8">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="8xc-J0-7iQ"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="83"/>
<menuItem title="Player" id="633">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Screen" id="295"/>
<menuItem title="窗口" id="19">
<menu key="submenu" title="窗口" systemMenu="window" id="XuB-dT-g0h">
<items>
<menuItem title="最小化" keyEquivalent="m" id="YrK-j5-jxq">
<connections>
<action selector="performMiniaturize:" target="-1" id="3wr-0O-cTq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="0NY-jh-tsl">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="移到最上层" id="opb-EX-EXV">
<connections>
<action selector="arrangeInFront:" target="-1" id="oT1-07-BON"/>
</connections>
</menuItem>
<menuItem title="置顶" keyEquivalent="a" id="nXh-Uq-d6d">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="onWindowAlwaysOnTop:" target="-1" id="IM6-Km-MGj"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="帮助" id="490">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="帮助" systemMenu="help" id="UaO-03-xh1">
<items>
<menuItem title="帮助文档" keyEquivalent="?" id="StN-Og-Ms8">
<connections>
<action selector="showHelp:" target="-1" id="l0h-I0-XAk"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<customObject id="420" customClass="NSFontManager"/>
<customObject id="536" customClass="AppController">
<connections>
<outlet property="menu" destination="29" id="550"/>
</connections>
</customObject>
</objects>
</document>

View File

@ -68,7 +68,7 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\Classes\runtime;$(ProjectDir)..\Classes\protobuf-lite;$(EngineRoot)external\win32-specific\zlib\include;$(EngineRoot)cocos\scripting\lua-bindings\auto;$(EngineRoot)cocos\scripting\lua-bindings\manual;$(EngineRoot)cocos\audio\include;$(EngineRoot)external;$(EngineRoot)external\lua\lua;$(EngineRoot)external\lua\tolua;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)extensions;$(EngineRoot);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\Classes\runtime;$(ProjectDir)..\Classes\service;$(ProjectDir)..\Classes\protobuf-lite;$(EngineRoot)external\win32-specific\zlib\include;$(EngineRoot)cocos\scripting\lua-bindings\auto;$(EngineRoot)cocos\scripting\lua-bindings\manual;$(EngineRoot)cocos\audio\include;$(EngineRoot)external;$(EngineRoot)external\lua\lua;$(EngineRoot)external\lua\tolua;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)external\curl\include\win32;$(EngineRoot)extensions;$(EngineRoot);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
@ -119,7 +119,8 @@
</Command>
</PreLinkEvent>
<PostBuildEvent>
<Command>xcopy /Y /Q "$(OutDir)*.dll" "$(ProjectDir)..\..\..\runtime\win32\"</Command>
<Command>xcopy /Y /Q "$(OutDir)*.dll" "$(ProjectDir)..\..\..\runtime\win32\"
xcopy /Y /Q "$(ProjectDir)..\Classes\lang" "$(ProjectDir)..\..\..\runtime\win32\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -164,24 +165,25 @@
</DllDataFileName>
</Midl>
<PreBuildEvent>
<Command>if exist "$(LocalDebuggerWorkingDirectory)" rd /s /q "$(LocalDebuggerWorkingDirectory)"
mkdir "$(LocalDebuggerWorkingDirectory)"
mkdir "$(LocalDebuggerWorkingDirectory)\src"
mkdir "$(LocalDebuggerWorkingDirectory)\res"
xcopy "$(ProjectDir)..\..\..\src" "$(LocalDebuggerWorkingDirectory)\src" /e /Y
xcopy "$(ProjectDir)..\..\..\res" "$(LocalDebuggerWorkingDirectory)\res" /e /Y
copy "$(ProjectDir)..\..\..\config.json" "$(LocalDebuggerWorkingDirectory)\config.json" /Y
</Command>
<Command>if not exist "$(LocalDebuggerWorkingDirectory)" mkdir "$(LocalDebuggerWorkingDirectory)"</Command>
<Message>copy files</Message>
</PreBuildEvent>
<PreLinkEvent>
<Command>
</Command>
</PreLinkEvent>
<PostBuildEvent>
<Command>xcopy /Y /Q "$(OutDir)*.dll" "$(ProjectDir)..\..\..\runtime\win32\"
xcopy /Y /Q "$(ProjectDir)..\Classes\lang" "$(ProjectDir)..\..\..\runtime\win32\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\Classes\AppDelegate.h" />
<ClInclude Include="..\Classes\ConfigParser.h" />
<ClInclude Include="..\Classes\network\CCHTTPRequest.h" />
<ClInclude Include="..\Classes\network\CCHTTPRequestDelegate.h" />
<ClInclude Include="..\Classes\ProjectConfig\ProjectConfig.h" />
<ClInclude Include="..\Classes\ProjectConfig\SimulatorConfig.h" />
<ClInclude Include="..\Classes\protobuf-lite\google\protobuf\extension_set.h" />
<ClInclude Include="..\Classes\protobuf-lite\google\protobuf\generated_message_util.h" />
<ClInclude Include="..\Classes\protobuf-lite\google\protobuf\io\coded_stream.h" />
@ -210,14 +212,37 @@ copy "$(ProjectDir)..\..\..\config.json" "$(LocalDebuggerWorkingDirectory)\confi
<ClInclude Include="..\Classes\runtime\Protos.pb.h" />
<ClInclude Include="..\Classes\runtime\ResData.h" />
<ClInclude Include="..\Classes\runtime\Runtime.h" />
<ClInclude Include="..\Classes\service\AppEvent.h" />
<ClInclude Include="..\Classes\service\AppLang.h" />
<ClInclude Include="..\Classes\service\DeviceEx.h" />
<ClInclude Include="..\Classes\service\PlayerEditBoxServiceProtocol.h" />
<ClInclude Include="..\Classes\service\PlayerFileDialogServiceProtocol.h" />
<ClInclude Include="..\Classes\service\PlayerMacros.h" />
<ClInclude Include="..\Classes\service\PlayerMenuServiceProtocol.h" />
<ClInclude Include="..\Classes\service\PlayerMessageBoxServiceProtocol.h" />
<ClInclude Include="..\Classes\service\PlayerProtocol.h" />
<ClInclude Include="..\Classes\service\PlayerServiceProtocol.h" />
<ClInclude Include="..\Classes\service\PlayerSettings.h" />
<ClInclude Include="..\Classes\service\PlayerTaskServiceProtocol.h" />
<ClInclude Include="..\Classes\service\PlayerUtils.h" />
<ClInclude Include="..\Classes\VisibleRect.h" />
<ClInclude Include="main.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SimulatorWindow.h" />
<ClInclude Include="service\PlayerEditBoxServiceWin.h" />
<ClInclude Include="service\PlayerFileDialogServiceWin.h" />
<ClInclude Include="service\PlayerMenuServiceWin.h" />
<ClInclude Include="service\PlayerMessageBoxServiceWin.h" />
<ClInclude Include="service\PlayerTaskServiceWin.h" />
<ClInclude Include="service\PlayerWin.h" />
<ClInclude Include="service\stdafx.h" />
<ClInclude Include="service\targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\Classes\AppDelegate.cpp" />
<ClCompile Include="..\Classes\ConfigParser.cpp" />
<ClCompile Include="..\Classes\network\CCHTTPRequest.cpp" />
<ClCompile Include="..\Classes\ProjectConfig\ProjectConfig.cpp" />
<ClCompile Include="..\Classes\ProjectConfig\SimulatorConfig.cpp" />
<ClCompile Include="..\Classes\protobuf-lite\google\protobuf\extension_set.cc" />
<ClCompile Include="..\Classes\protobuf-lite\google\protobuf\generated_message_util.cc" />
<ClCompile Include="..\Classes\protobuf-lite\google\protobuf\io\coded_stream.cc" />
@ -241,10 +266,25 @@ copy "$(ProjectDir)..\..\..\config.json" "$(LocalDebuggerWorkingDirectory)\confi
<ClCompile Include="..\Classes\runtime\Protos.pb.cc" />
<ClCompile Include="..\Classes\runtime\Runtime.cpp" />
<ClCompile Include="..\Classes\runtime\Shine_png.cpp" />
<ClCompile Include="..\Classes\service\AppEvent.cpp" />
<ClCompile Include="..\Classes\service\AppLang.cpp" />
<ClCompile Include="..\Classes\service\PlayerMenuServiceProtocol.cpp" />
<ClCompile Include="..\Classes\service\PlayerProtocol.cpp" />
<ClCompile Include="..\Classes\service\PlayerServiceProtocol.cpp" />
<ClCompile Include="..\Classes\service\PlayerSettings.cpp" />
<ClCompile Include="..\Classes\service\PlayerTaskServiceProtocol.cpp" />
<ClCompile Include="..\Classes\service\PlayerUtils.cpp" />
<ClCompile Include="..\Classes\VisibleRect.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="Runtime_win32.cpp" />
<ClCompile Include="SimulatorWindow.cpp" />
<ClCompile Include="service\DeviceEx-win32.cpp" />
<ClCompile Include="service\PlayerEditBoxServiceWin.cpp" />
<ClCompile Include="service\PlayerFileDialogServiceWin.cpp" />
<ClCompile Include="service\PlayerMenuServiceWin.cpp" />
<ClCompile Include="service\PlayerMessageBoxServiceWin.cpp" />
<ClCompile Include="service\PlayerTaskServiceWin.cpp" />
<ClCompile Include="service\PlayerWin.cpp" />
<ClCompile Include="service\stdafx.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="game.rc" />

View File

@ -16,6 +16,18 @@
<Filter Include="Classes\runtime\protobuf-lite">
<UniqueIdentifier>{28edb895-7c19-408b-abd6-130196087d96}</UniqueIdentifier>
</Filter>
<Filter Include="Classes\service">
<UniqueIdentifier>{b0ffeea4-e5fa-483a-8be4-c26a9ed47c60}</UniqueIdentifier>
</Filter>
<Filter Include="Classes\network">
<UniqueIdentifier>{e2010b29-c067-4846-8f28-667d95056987}</UniqueIdentifier>
</Filter>
<Filter Include="Classes\ProjectConfig">
<UniqueIdentifier>{6a6237c1-312d-4c66-82b3-b0de869920c8}</UniqueIdentifier>
</Filter>
<Filter Include="win32\service">
<UniqueIdentifier>{9d6fbab4-6525-4c43-9438-9d3923429d52}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Classes\AppDelegate.h">
@ -24,9 +36,6 @@
<ClInclude Include="main.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="SimulatorWindow.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="resource.h" />
<ClInclude Include="..\Classes\ConfigParser.h">
<Filter>Classes</Filter>
@ -118,6 +127,81 @@
<ClInclude Include="..\Classes\runtime\FileServer.h">
<Filter>Classes\runtime</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\AppEvent.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\AppLang.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\DeviceEx.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerEditBoxServiceProtocol.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerFileDialogServiceProtocol.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerMacros.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerMenuServiceProtocol.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerMessageBoxServiceProtocol.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerProtocol.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerServiceProtocol.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerSettings.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerTaskServiceProtocol.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\service\PlayerUtils.h">
<Filter>Classes\service</Filter>
</ClInclude>
<ClInclude Include="..\Classes\network\CCHTTPRequest.h">
<Filter>Classes\network</Filter>
</ClInclude>
<ClInclude Include="..\Classes\network\CCHTTPRequestDelegate.h">
<Filter>Classes\network</Filter>
</ClInclude>
<ClInclude Include="..\Classes\ProjectConfig\ProjectConfig.h">
<Filter>Classes\ProjectConfig</Filter>
</ClInclude>
<ClInclude Include="..\Classes\ProjectConfig\SimulatorConfig.h">
<Filter>Classes\ProjectConfig</Filter>
</ClInclude>
<ClInclude Include="service\PlayerEditBoxServiceWin.h">
<Filter>win32\service</Filter>
</ClInclude>
<ClInclude Include="service\PlayerFileDialogServiceWin.h">
<Filter>win32\service</Filter>
</ClInclude>
<ClInclude Include="service\PlayerMenuServiceWin.h">
<Filter>win32\service</Filter>
</ClInclude>
<ClInclude Include="service\PlayerMessageBoxServiceWin.h">
<Filter>win32\service</Filter>
</ClInclude>
<ClInclude Include="service\PlayerTaskServiceWin.h">
<Filter>win32\service</Filter>
</ClInclude>
<ClInclude Include="service\PlayerWin.h">
<Filter>win32\service</Filter>
</ClInclude>
<ClInclude Include="service\stdafx.h">
<Filter>win32\service</Filter>
</ClInclude>
<ClInclude Include="service\targetver.h">
<Filter>win32\service</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\Classes\AppDelegate.cpp">
@ -126,9 +210,6 @@
<ClCompile Include="main.cpp">
<Filter>win32</Filter>
</ClCompile>
<ClCompile Include="SimulatorWindow.cpp">
<Filter>win32</Filter>
</ClCompile>
<ClCompile Include="Runtime_win32.cpp">
<Filter>win32</Filter>
</ClCompile>
@ -207,6 +288,63 @@
<ClCompile Include="..\Classes\runtime\FileServer.cpp">
<Filter>Classes\runtime</Filter>
</ClCompile>
<ClCompile Include="..\Classes\service\AppEvent.cpp">
<Filter>Classes\service</Filter>
</ClCompile>
<ClCompile Include="..\Classes\service\AppLang.cpp">
<Filter>Classes\service</Filter>
</ClCompile>
<ClCompile Include="..\Classes\service\PlayerMenuServiceProtocol.cpp">
<Filter>Classes\service</Filter>
</ClCompile>
<ClCompile Include="..\Classes\service\PlayerProtocol.cpp">
<Filter>Classes\service</Filter>
</ClCompile>
<ClCompile Include="..\Classes\service\PlayerServiceProtocol.cpp">
<Filter>Classes\service</Filter>
</ClCompile>
<ClCompile Include="..\Classes\service\PlayerSettings.cpp">
<Filter>Classes\service</Filter>
</ClCompile>
<ClCompile Include="..\Classes\service\PlayerTaskServiceProtocol.cpp">
<Filter>Classes\service</Filter>
</ClCompile>
<ClCompile Include="..\Classes\service\PlayerUtils.cpp">
<Filter>Classes\service</Filter>
</ClCompile>
<ClCompile Include="..\Classes\network\CCHTTPRequest.cpp">
<Filter>Classes\network</Filter>
</ClCompile>
<ClCompile Include="..\Classes\ProjectConfig\ProjectConfig.cpp">
<Filter>Classes\ProjectConfig</Filter>
</ClCompile>
<ClCompile Include="..\Classes\ProjectConfig\SimulatorConfig.cpp">
<Filter>Classes\ProjectConfig</Filter>
</ClCompile>
<ClCompile Include="service\DeviceEx-win32.cpp">
<Filter>win32\service</Filter>
</ClCompile>
<ClCompile Include="service\PlayerEditBoxServiceWin.cpp">
<Filter>win32\service</Filter>
</ClCompile>
<ClCompile Include="service\PlayerFileDialogServiceWin.cpp">
<Filter>win32\service</Filter>
</ClCompile>
<ClCompile Include="service\PlayerMenuServiceWin.cpp">
<Filter>win32\service</Filter>
</ClCompile>
<ClCompile Include="service\PlayerMessageBoxServiceWin.cpp">
<Filter>win32\service</Filter>
</ClCompile>
<ClCompile Include="service\PlayerTaskServiceWin.cpp">
<Filter>win32\service</Filter>
</ClCompile>
<ClCompile Include="service\PlayerWin.cpp">
<Filter>win32\service</Filter>
</ClCompile>
<ClCompile Include="service\stdafx.cpp">
<Filter>win32\service</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="game.rc">

View File

@ -6,6 +6,7 @@
#include <string>
#include "cocos2d.h"
#include "ConfigParser.h"
using namespace std;
string getIPAddress()
@ -15,6 +16,13 @@ string getIPAddress()
char *ip=nullptr;
PHOSTENT hostinfo;
// customized by user
auto &bindAddress = ConfigParser::getInstance()->getBindAddress();
if (!bindAddress.empty())
{
return bindAddress;
}
if ( WSAStartup( MAKEWORD(2,0), &wsaData ) == 0 )
{
if( gethostname ( name, sizeof(name)) == 0)

View File

@ -1,369 +0,0 @@
/****************************************************************************
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 "SimulatorWindow.h"
#include "cocos2d.h"
#include "resource.h"
#include "runtime/Runtime.h"
#include "ConfigParser.h"
#include <string>
#include <vector>
using namespace std;
using namespace cocos2d;
WNDPROC g_oldProc=NULL;
bool g_landscape=false;
bool g_windTop = false;
CCSize g_screenSize;
GLView* g_eglView=NULL;
INT_PTR CALLBACK AboutDialogCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void createViewMenu()
{
HMENU hSysMenu = GetSystemMenu(g_eglView->getWin32Window(), FALSE);
HMENU viewMenu = GetSubMenu(hSysMenu, 8);
for (int i = ConfigParser::getInstance()->getScreenSizeCount() - 1; i >= 0; --i)
{
SimulatorScreenSize size = ConfigParser::getInstance()->getScreenSize(i);
wstring menuName;
menuName.assign(size.title.begin(), size.title.end());
MENUITEMINFO item;
ZeroMemory(&item, sizeof(item));
item.cbSize = sizeof(item);
item.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
item.fType = MFT_STRING;
item.wID = ID_VIEW_SIZE + i;
item.dwTypeData = (LPTSTR)menuName.c_str();
item.cch = menuName.length();
InsertMenuItem(viewMenu, 0, TRUE, &item);
}
}
void updateMenu()
{
HMENU hSysMenu = GetSystemMenu(g_eglView->getWin32Window(), FALSE);
HMENU viewMenu = GetSubMenu(hSysMenu, 8);
HMENU viewControl = GetSubMenu(hSysMenu, 9);
if (g_landscape)
{
CheckMenuItem(viewMenu, ID_VIEW_PORTRAIT, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(viewMenu, ID_VIEW_LANDSCAPE, MF_BYCOMMAND | MF_CHECKED);
}
else
{
CheckMenuItem(viewMenu, ID_VIEW_PORTRAIT, MF_BYCOMMAND | MF_CHECKED);
CheckMenuItem(viewMenu, ID_VIEW_LANDSCAPE, MF_BYCOMMAND | MF_UNCHECKED);
}
if (g_windTop)
{
::SetWindowPos(g_eglView->getWin32Window(),HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
CheckMenuItem(viewControl, ID_CONTROL_TOP, MF_BYCOMMAND | MF_CHECKED);
}else
{
::SetWindowPos(g_eglView->getWin32Window(),HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
CheckMenuItem(viewControl, ID_CONTROL_TOP, MF_BYCOMMAND | MF_UNCHECKED);
}
int width = g_screenSize.width;
int height = g_screenSize.height;
if (height > width)
{
int w = width;
width = height;
height = w;
}
int count = ConfigParser::getInstance()->getScreenSizeCount();
for (int i = 0; i < count; ++i)
{
bool bSel = false;
SimulatorScreenSize size = ConfigParser::getInstance()->getScreenSize(i);
if (size.width == width && size.height == height)
{
bSel = true;
}
CheckMenuItem(viewMenu, i, MF_BYPOSITION | (bSel? MF_CHECKED : MF_UNCHECKED));
}
int scale=g_eglView->getFrameZoomFactor()*100;
CheckMenuItem(viewMenu, ID_VIEW_ZOOMOUT100, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(viewMenu, ID_VIEW_ZOOMOUT75, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(viewMenu, ID_VIEW_ZOOMOUT50, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(viewMenu, ID_VIEW_ZOOMOUT25, MF_BYCOMMAND | MF_UNCHECKED);
switch (scale)
{
case 100:
CheckMenuItem(viewMenu, ID_VIEW_ZOOMOUT100, MF_BYCOMMAND | MF_CHECKED);
break;
case 75:
CheckMenuItem(viewMenu, ID_VIEW_ZOOMOUT75, MF_BYCOMMAND | MF_CHECKED);
break;
case 50:
CheckMenuItem(viewMenu, ID_VIEW_ZOOMOUT50, MF_BYCOMMAND | MF_CHECKED);
break;
case 25:
CheckMenuItem(viewMenu, ID_VIEW_ZOOMOUT25, MF_BYCOMMAND | MF_CHECKED);
break;
default:
break;
}
}
/*@brief updateView*/
void updateView()
{
auto policy = g_eglView->getResolutionPolicy();
auto designSize = g_eglView->getDesignResolutionSize();
if (g_landscape)
{
g_eglView->setFrameSize(g_screenSize.width, g_screenSize.height);
}
else
{
g_eglView->setFrameSize(g_screenSize.height, g_screenSize.width);
}
g_eglView->setDesignResolutionSize(designSize.width, designSize.height, policy);
updateMenu();
}
void onViewChangeOrientation(int viewMenuID)
{
if (viewMenuID == ID_VIEW_PORTRAIT && g_landscape)
{
g_landscape = false;
updateView();
}
else if (viewMenuID == ID_VIEW_LANDSCAPE && !g_landscape)
{
g_landscape = true;
updateView();
}
}
void onViewZoomOut(int viewMenuID)
{
float scale = 1.0;
switch (viewMenuID)
{
case ID_VIEW_ZOOMOUT100:
scale=1.0;
break;
case ID_VIEW_ZOOMOUT75:
scale=0.75;
break;
case ID_VIEW_ZOOMOUT50:
scale=0.50;
break;
case ID_VIEW_ZOOMOUT25:
scale=0.25;
break;
default:
break;
}
dynamic_cast<GLViewImpl*>(g_eglView)->setFrameZoomFactor(scale);
updateView();
}
void onViewChangeFrameSize(int viewMenuID)
{
int index = viewMenuID - ID_VIEW_SIZE;
if (index >= 0 && index < ConfigParser::getInstance()->getScreenSizeCount())
{
SimulatorScreenSize size = ConfigParser::getInstance()->getScreenSize(index);
g_screenSize.width = size.width;
g_screenSize.height = size.height;
updateView();
}
}
void onHelpAbout()
{
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG_ABOUT), g_eglView->getWin32Window(), AboutDialogCallback);
}
void shutDownApp()
{
HWND hWnd=g_eglView->getWin32Window();
::SendMessage(hWnd,WM_CLOSE,NULL,NULL);
}
void reStart()
{
PROCESS_INFORMATION info;
STARTUPINFO startup;
TCHAR szPath[128]={0};
TCHAR *szCmdLine=NULL;
GetModuleFileName(NULL, szPath, sizeof(szPath));
szCmdLine = GetCommandLine();
GetStartupInfo(&startup);
BOOL bSucc = CreateProcess(szPath, szCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &info);
if(bSucc)
{
ExitProcess(-1);
}
}
/*@brief new windows process*/
LRESULT CALLBACK SNewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_KEYDOWN:
if (wParam == VK_F5)
{
reStart();
break;
}
case WM_SYSCOMMAND:
{
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_CONTROL_TOP:
g_windTop = !g_windTop;
updateView();
break;
case ID_FILE_EXIT:
shutDownApp();
break;
case ID_VIEW_PORTRAIT:
case ID_VIEW_LANDSCAPE:
onViewChangeOrientation(wmId);
break;
case ID_VIEW_ZOOMOUT100:
case ID_VIEW_ZOOMOUT75:
case ID_VIEW_ZOOMOUT50:
case ID_VIEW_ZOOMOUT25:
onViewZoomOut(wmId);
break;
case ID_CONTROL_RELOAD:
reStart();
break;
case ID_HELP_ABOUT:
onHelpAbout();
break;
default:
if (wmId >= ID_VIEW_SIZE && wmId <= ID_VIEW_SIZE + ConfigParser::getInstance()->getScreenSizeCount() - 1)
{
onViewChangeFrameSize(wmId);
break;
}
//return 0;
}
}
break;
}
return g_oldProc(hWnd, message, wParam, lParam);
}
/*@brief AboutDialog Callback*/
INT_PTR CALLBACK AboutDialogCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
void createSimulator(const char* viewName, float width, float height, bool isLandscape, float frameZoomFactor)
{
if (g_eglView)
{
return;
}
g_landscape = isLandscape;
if(height > width)
{
float tmpvalue =width;
width = height;
height = tmpvalue;
}
g_screenSize.width = width;
g_screenSize.height = height;
if(!g_landscape)
{
float tmpvalue =width;
width = height;
height = tmpvalue;
}
g_windTop = ConfigParser::getInstance()->isWindowTop();
g_eglView = GLViewImpl::createWithRect(viewName,Rect(0,0,width,height),frameZoomFactor);
auto director = Director::getInstance();
director->setOpenGLView(g_eglView);
HWND hWnd=g_eglView->getWin32Window();
HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MENU_COCOS));
HMENU hSysMenu = GetSystemMenu(hWnd, FALSE);
HMENU hviewMenu = GetSubMenu(hMenu,1);
HMENU hcontrolMenu = GetSubMenu(hMenu,2);
AppendMenu(hSysMenu,MF_SEPARATOR,0,NULL);
if (hSysMenu != INVALID_HANDLE_VALUE && hMenu != INVALID_HANDLE_VALUE)
{
AppendMenu(hSysMenu, MF_POPUP, (UINT)hviewMenu, TEXT("view"));
AppendMenu(hSysMenu, MF_POPUP, (UINT)hcontrolMenu, TEXT("control"));
}
//SetMenu(hWnd, hMenu);
createViewMenu();
updateMenu();
g_oldProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (LONG)SNewWndProc);
if (g_oldProc==0)
{
printf("SetWindowLong NewWndProc Error:%d\n",GetLastError());
}
}

View File

@ -1,33 +0,0 @@
/****************************************************************************
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 __SIMULATOR_WINDOW_H_
#define __SIMULATOR_WINDOW_H_
/************************
@brief create Simulator
*********************************/
void createSimulator(const char* viewName, float width, float height,bool isLandscape = true,float frameZoomFactor = 1.0f);
#endif /* __PROJECT_CONFIG_H_ */

View File

@ -47,30 +47,9 @@ END
IDR_MENU_COCOS MENU
BEGIN
POPUP "&File"
POPUP "°ïÖú(&H)"
BEGIN
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&View"
BEGIN
MENUITEM SEPARATOR
MENUITEM "&Portrait", ID_VIEW_PORTRAIT
MENUITEM "&Landscape", ID_VIEW_LANDSCAPE
MENUITEM SEPARATOR
MENUITEM "&Actual(100%)", ID_VIEW_ZOOMOUT100
MENUITEM "Zoom Out(75%)", ID_VIEW_ZOOMOUT75
MENUITEM "Zoom Out(50%)", ID_VIEW_ZOOMOUT50
MENUITEM "Zoom Out(25%)", ID_VIEW_ZOOMOUT25
END
POPUP "&Control"
BEGIN
MENUITEM "Restart(F5)", ID_CONTROL_RELOAD
MENUITEM "Keep Window Top", ID_CONTROL_TOP
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", ID_HELP_ABOUT
MENUITEM "¹ØÓÚ(&A)", ID_HELP_ABOUT
END
END
@ -86,7 +65,7 @@ CAPTION "About Simulator"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,173,69,63,18
LTEXT "Cocos2d-x-Simulator",IDC_STATIC,29,17,169,25
CTEXT "Cocos Simulator",IDC_STATIC,28,23,173,17
END
@ -112,6 +91,30 @@ END
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
#pragma code_page(1252)
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU_COCOS MENU
BEGIN
POPUP "&Help"
BEGIN
MENUITEM "&About ...", ID_HELP_ABOUT
END
END
#endif // English resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources

View File

@ -1,73 +1,14 @@
#include "main.h"
#include "AppDelegate.h"
#include "cocos2d.h"
#include "service/PlayerWin.h"
#include <shellapi.h>
USING_NS_CC;
// uncomment below line, open debug console
//#define USE_WIN32_CONSOLE
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
LPWSTR *szArgList=nullptr;
int argCount=0;
szArgList = CommandLineToArgvW(GetCommandLine(),&argCount);
if (argCount >=2 )
{
int iLen = 2*wcslen(szArgList[1]);
char* chRtn = new char[iLen+1];
wcstombs(chRtn,szArgList[1],iLen+1);
delete [] chRtn;
}
LocalFree(szArgList);
#ifdef USE_WIN32_CONSOLE
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
#endif
// create the application instance
AppDelegate app;
int ret = Application::getInstance()->run();
#ifdef USE_WIN32_CONSOLE
if (!ret)
{
system("pause");
}
FreeConsole();
#endif
return ret;
}
std::string getCurAppPath(void)
{
TCHAR szAppDir[MAX_PATH]={0};
if (!GetModuleFileName(NULL,szAppDir,MAX_PATH))
return "";
int nEnd=0;
for (int i=0;szAppDir[i];i++)
{
if(szAppDir[i]=='\\')
nEnd = i;
}
szAppDir[nEnd] = 0;
int iLen = 2*wcslen(szAppDir);
char* chRtn = new char[iLen+1];
wcstombs(chRtn,szAppDir,iLen+1);
std::string strPath = chRtn;
delete [] chRtn;
chRtn=NULL;
char fuldir[MAX_PATH]={0};
_fullpath(fuldir,strPath.c_str(),MAX_PATH);
return fuldir;
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
auto player = player::PlayerWin::getInstance();
return player->run();
}

View File

@ -0,0 +1,137 @@
#include "DeviceEx.h"
// for mac address
#include <WinSock2.h>
#include <Iphlpapi.h>
#pragma comment(lib,"Iphlpapi.lib")
using namespace std;
PLAYER_NS_BEGIN
DeviceEx *DeviceEx::getInstance()
{
static DeviceEx *instance = NULL;
if (!instance)
{
instance = new DeviceEx();
instance->init();
}
return instance;
}
std::string DeviceEx::getCurrentUILangName()
{
return _uiLangName;
}
std::string DeviceEx::getUserGUID()
{
return _userGUID;
}
////////// private //////////
DeviceEx::DeviceEx()
: _uiLangName("en")
{
}
void DeviceEx::init()
{
makeUILangName();
makeUserGUID();
}
void DeviceEx::makeUILangName()
{
//
// get language
// http://msdn.microsoft.com/en-us/library/windows/apps/jj244362(v=vs.105).aspx
//
ULONG numLanguages = 0;
DWORD cchLanguagesBuffer = 0;
BOOL hr = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLanguages, NULL, &cchLanguagesBuffer);
if (hr)
{
WCHAR* pwszLanguagesBuffer = new WCHAR[cchLanguagesBuffer];
hr = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLanguages, pwszLanguagesBuffer, &cchLanguagesBuffer);
if (hr)
{
size_t size = wcslen(pwszLanguagesBuffer) * 3 + 1;
char* dest = new char[size];
memset(dest, 0, size);
WideCharToMultiByte(CP_UTF8, 0, pwszLanguagesBuffer, -1, dest, size, NULL, NULL);
_uiLangName = dest;
}
delete pwszLanguagesBuffer;
}
}
static bool getMacAddress(string& macstring)
{
bool ret = false;
ULONG ipInfoLen = sizeof(IP_ADAPTER_INFO);
PIP_ADAPTER_INFO adapterInfo = (IP_ADAPTER_INFO *)malloc(ipInfoLen);
if (adapterInfo == NULL)
{
return false;
}
if (GetAdaptersInfo(adapterInfo, &ipInfoLen) == ERROR_BUFFER_OVERFLOW)
{
free(adapterInfo);
adapterInfo = (IP_ADAPTER_INFO *)malloc(ipInfoLen);
if (adapterInfo == NULL)
{
return false;
}
}
if (GetAdaptersInfo(adapterInfo, &ipInfoLen) == NO_ERROR)
{
for (PIP_ADAPTER_INFO pAdapter = adapterInfo; pAdapter != NULL; pAdapter = pAdapter->Next)
{
if (pAdapter->Type != MIB_IF_TYPE_ETHERNET)
{
continue;
}
if (pAdapter->AddressLength != 6)
{
continue;
}
char buf32[32];
sprintf(buf32, "%02X-%02X-%02X-%02X-%02X-%02X",
int(pAdapter->Address[0]),
int(pAdapter->Address[1]),
int(pAdapter->Address[2]),
int(pAdapter->Address[3]),
int(pAdapter->Address[4]),
int(pAdapter->Address[5]));
macstring = buf32;
ret = true;
break;
}
}
free(adapterInfo);
return ret;
}
std::string DeviceEx::makeUserGUID()
{
if (_userGUID.length() <= 0)
{
if (!getMacAddress(_userGUID))
{
_userGUID = "guid-fixed-1234567890";
}
}
return _userGUID;
}
PLAYER_NS_END

View File

@ -0,0 +1,98 @@
#include <string>
#include "stdafx.h"
#include "cocos2d.h"
#include "PlayerEditBoxServiceWin.h"
PLAYER_NS_BEGIN
PlayerEditBoxServiceWin::PlayerEditBoxServiceWin(HWND hwnd)
: _hfont(NULL)
{
_hwnd = hwnd;
HINSTANCE instance = (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE);
DWORD style = WS_CHILD | ES_LEFT | ES_AUTOHSCROLL;
_hwndSingle = CreateWindowEx(WS_EX_CLIENTEDGE, L"Edit", L"", style, 0, 0, 0, 0, _hwnd, NULL, instance, NULL);
style = WS_CHILD | ES_MULTILINE | ES_LEFT | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL;
_hwndMulti = CreateWindowEx(WS_EX_CLIENTEDGE, L"Edit", L"", style, 0, 0, 0, 0, _hwnd, NULL, instance, NULL);
}
PlayerEditBoxServiceWin::~PlayerEditBoxServiceWin()
{
removeFont();
DestroyWindow(_hwndSingle);
DestroyWindow(_hwndMulti);
}
void PlayerEditBoxServiceWin::showSingleLineEditBox(const cocos2d::Rect &rect)
{
MoveWindow(_hwndSingle, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height, TRUE);
ShowWindow(_hwndSingle, SW_SHOW);
SetFocus(_hwndSingle);
}
void PlayerEditBoxServiceWin::showMultiLineEditBox(const cocos2d::Rect &rect)
{
MoveWindow(_hwndMulti, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height, TRUE);
ShowWindow(_hwndMulti, SW_SHOW);
SetFocus(_hwndMulti);
}
void PlayerEditBoxServiceWin::hide()
{
}
void PlayerEditBoxServiceWin::setText(const std::string &text)
{
}
void PlayerEditBoxServiceWin::setFont(const std::string &name, int size)
{
removeFont();
std::u16string u16name;
cocos2d::StringUtils::UTF8ToUTF16(name, u16name);
HDC hdc = GetDC(_hwnd);
size = -MulDiv(size, GetDeviceCaps(hdc, LOGPIXELSY), 72);
ReleaseDC(_hwnd, hdc);
_hfont = CreateFont(size, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
0, OUT_DEFAULT_PRECIS, FW_NORMAL, DEFAULT_QUALITY, DEFAULT_PITCH,
(LPCTSTR)u16name.c_str());
if (!_hfont)
{
DWORD err = GetLastError();
CCLOG("PlayerEditBoxServiceWin::setFont() - create HFONT for font \"%s\" failed, error code = 0x%08x",
name.c_str(), err);
}
else
{
SendMessage(_hwndSingle, WM_SETFONT, (WPARAM)_hfont, NULL);
SendMessage(_hwndMulti, WM_SETFONT, (WPARAM)_hfont, NULL);
}
}
void PlayerEditBoxServiceWin::setFontColor(const cocos2d::Color3B &color)
{
}
void PlayerEditBoxServiceWin::removeFont()
{
if (_hfont)
{
SendMessage(_hwndSingle, WM_SETFONT, NULL, NULL);
SendMessage(_hwndMulti, WM_SETFONT, NULL, NULL);
DeleteObject(_hfont);
}
_hfont = NULL;
}
void PlayerEditBoxServiceWin::setFormator(int /*formator*/ )
{
}
PLAYER_NS_END

View File

@ -0,0 +1,36 @@
#ifndef __PLAYER_EDITBOX_SERVICE_WIN_H_
#define __PLAYER_EDITBOX_SERVICE_WIN_H_
#include "stdafx.h"
#include "PlayerEditBoxServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerEditBoxServiceWin : public PlayerEditBoxServiceProtocol
{
public:
PlayerEditBoxServiceWin(HWND hwnd);
virtual ~PlayerEditBoxServiceWin();
virtual void showSingleLineEditBox(const cocos2d::Rect &rect);
virtual void showMultiLineEditBox(const cocos2d::Rect &rect);
virtual void hide();
virtual void setText(const std::string &text);
virtual void setFont(const std::string &name, int size);
virtual void setFontColor(const cocos2d::Color3B &color);
virtual void setFormator(int formator);
protected:
HWND _hwnd;
HWND _hwndSingle;
HWND _hwndMulti;
HFONT _hfont;
void removeFont();
};
PLAYER_NS_END
#endif // __PLAYER_EDITBOX_SERVICE_WIN_H_

View File

@ -0,0 +1,265 @@
#include <string.h>
#include "stdafx.h"
#include <Windowsx.h>
#include <Shlobj.h>
#include <Commdlg.h>
#include "cocos2d.h"
#include "PlayerUtils.h"
#include "PlayerFileDialogServiceWin.h"
PLAYER_NS_BEGIN
PlayerFileDialogServiceWin::PlayerFileDialogServiceWin(HWND hwnd)
: _hwnd(hwnd)
{
}
std::string PlayerFileDialogServiceWin::openFile(const std::string &title,
const std::string &directory,
const std::string &extensions) const
{
vector<std::string> result = openMultipleInternal(title, directory, extensions, false);
if (result.size())
{
return result.at(0);
}
return std::string();
}
std::vector<std::string> PlayerFileDialogServiceWin::openMultiple(const std::string &title,
const std::string &directory,
const std::string &extensions) const
{
return openMultipleInternal(title, directory, extensions, true);
}
std::string PlayerFileDialogServiceWin::saveFile(const std::string &title,
const std::string &path) const
{
std::u16string u16title;
cocos2d::StringUtils::UTF8ToUTF16(title, u16title);
WCHAR buff[MAX_PATH + 1] = {0};
if (path.length() > 0)
{
std::u16string u16filename;
cocos2d::StringUtils::UTF8ToUTF16(path, u16filename);
wcscpy_s(buff, (WCHAR*)u16filename.c_str());
}
OPENFILENAME ofn = {0};
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = _hwnd;
ofn.lpstrFilter = L"All Files (*.*)\0*.*\0";
ofn.lpstrTitle = (LPCTSTR)u16title.c_str();
ofn.Flags = OFN_DONTADDTORECENT | OFN_ENABLESIZING | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES;
ofn.lpstrFile = buff;
ofn.nMaxFile = MAX_PATH;
std::string result;
if (!GetSaveFileName(&ofn))
{
// user cancel dialog, GetSaveFileName() will return FALSE
DWORD err = CommDlgExtendedError();
if (err)
{
CCLOG("PlayerFileDialogServiceWin::saveFile() - failed, title (%s), error code = %u", title.c_str(), err);
}
return result;
}
cocos2d::StringUtils::UTF16ToUTF8((char16_t*)buff, result);
return result;
}
// for openDirectory
int CALLBACK BrowseFolderCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
if (uMsg == BFFM_INITIALIZED && lpData)
{
LPCTSTR path = (LPCTSTR)lpData;
SendMessage(hwnd, BFFM_SETSELECTION, true, (LPARAM)path);
}
return 0;
}
std::string PlayerFileDialogServiceWin::openDirectory(const std::string &title,
const std::string &directory) const
{
std::u16string u16title;
cocos2d::StringUtils::UTF8ToUTF16(title, u16title);
WCHAR basedir[MAX_PATH + 1];
if (directory.length())
{
std::u16string u16directory;
cocos2d::StringUtils::UTF8ToUTF16(directory, u16directory);
wcscpy_s(basedir, (WCHAR*)u16directory.c_str());
}
else
{
GetCurrentDirectory(MAX_PATH, basedir);
}
WCHAR buff[MAX_PATH + 1] = {0};
BROWSEINFO bi = {0};
bi.hwndOwner = _hwnd;
bi.pszDisplayName = buff;
bi.lpszTitle = (LPCTSTR)u16title.c_str();
bi.lParam = (LPARAM)basedir;
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NONEWFOLDERBUTTON | BIF_NEWDIALOGSTYLE;
bi.lpfn = BrowseFolderCallback;
PIDLIST_ABSOLUTE pid = SHBrowseForFolder(&bi);
if (pid)
{
SHGetPathFromIDList(pid, buff);
std::string result;
cocos2d::StringUtils::UTF16ToUTF8((char16_t*)buff, result);
return result;
}
else
{
return std::string("");
}
}
LPTSTR PlayerFileDialogServiceWin::parseExtensions(const std::string &extensions) const
{
static WCHAR *defaultExtensions = L"All Files (*.*)\0*.*\0";
if (extensions.length() == 0)
{
WCHAR *buff = new WCHAR[wcslen(defaultExtensions) + 1];
wcscpy(buff, defaultExtensions);
return buff;
}
// "Lua Script File|*.lua;JSON File|*.json"
// to
// "Lua Script File (*.lua)\0*.lua\0JSON File (*.json)\0*.json\0";
std::u16string u16extensions;
std::u16string split1((char16_t*)L";");
std::u16string split2((char16_t*)L"|");
cocos2d::StringUtils::UTF8ToUTF16(extensions, u16extensions);
vector<std::u16string> pairs = splitString(u16extensions, split1);
size_t buffsize = extensions.length() * 6;
WCHAR *buff = new WCHAR[buffsize];
memset(buff, 0, sizeof(WCHAR) * buffsize);
size_t offset = 0;
for (auto it = pairs.begin(); it != pairs.end(); ++it)
{
vector<std::u16string> p = splitString(*it, split2);
std::u16string descr, ext;
if (p.size() < 2)
{
descr = ext = *it;
}
else
{
descr = p.at(0);
ext = p.at(1);
}
wcscat(buff + offset, (WCHAR*)descr.c_str());
wcscat(buff + offset, L" (");
wcscat(buff + offset, (WCHAR*)ext.c_str());
wcscat(buff + offset, L")");
offset += descr.length() + ext.length() + 4;
wcscat(buff + offset, (WCHAR*)ext.c_str());
offset += ext.length() + 1;
}
return buff;
}
std::vector<std::string> PlayerFileDialogServiceWin::openMultipleInternal(const std::string &title,
const std::string &directory,
const std::string &extensions,
bool isMulti) const
{
std::u16string u16title;
cocos2d::StringUtils::UTF8ToUTF16(title, u16title);
WCHAR basedir[MAX_PATH + 1];
if (directory.length())
{
std::u16string u16directory;
cocos2d::StringUtils::UTF8ToUTF16(directory, u16directory);
wcscpy_s(basedir, (WCHAR*)u16directory.c_str());
}
else
{
GetCurrentDirectory(MAX_PATH, basedir);
}
size_t buffsize = MAX_PATH;
if (isMulti) buffsize = MAX_PATH * 64;
WCHAR *buff = new WCHAR[buffsize + 1];
memset(buff, 0, sizeof(WCHAR) * (buffsize + 1));
OPENFILENAME ofn = {0};
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = _hwnd;
ofn.lpstrFilter = parseExtensions(extensions);
ofn.lpstrTitle = (LPCTSTR)u16title.c_str();
ofn.lpstrInitialDir = basedir;
ofn.Flags = OFN_DONTADDTORECENT | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES;
if (isMulti) ofn.Flags |= OFN_ALLOWMULTISELECT | OFN_EXPLORER;
ofn.lpstrFile = buff;
ofn.nMaxFile = buffsize;
vector<std::string> result;
BOOL ret = GetOpenFileName(&ofn);
delete[] ofn.lpstrFilter;
if (!ret)
{
// user cancel dialog, GetOpenFileName() will return FALSE
DWORD err = CommDlgExtendedError();
if (err)
{
CCLOG("PlayerFileDialogServiceWin::openMultipleInternal() - failed, title (%s), error code = %u", title.c_str(), err);
}
delete[] buff;
return result;
}
if (isMulti)
{
WORD offset = 0;
std::string path;
while (buff[offset] != '\0')
{
std::string filename;
std::u16string u16filename((char16_t*)(buff + offset));
cocos2d::StringUtils::UTF16ToUTF8(u16filename, filename);
if (offset == 0)
{
path = filename;
if (path[path.length() - 1] != '\\')
{
path.append("\\");
}
}
else
{
result.push_back(path + filename);
}
offset += u16filename.length() + 1;
}
}
else
{
std::string path;
cocos2d::StringUtils::UTF16ToUTF8((char16_t*)buff, path);
result.push_back(path);
}
delete[] buff;
return result;
}
PLAYER_NS_END

View File

@ -0,0 +1,38 @@
#ifndef __PLAYER_FILE_DIALOG_SERVICE_WIN_H_
#define __PLAYER_FILE_DIALOG_SERVICE_WIN_H_
#include "stdafx.h"
#include "PlayerFileDialogServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerFileDialogServiceWin : public PlayerFileDialogServiceProtocol
{
public:
PlayerFileDialogServiceWin(HWND hwnd);
virtual std::string openFile(const std::string &title,
const std::string &directory,
const std::string &extensions) const;
virtual std::vector<std::string> openMultiple(const std::string &title,
const std::string &directory,
const std::string &extensions) const;
virtual std::string saveFile(const std::string &title,
const std::string &path) const;
virtual std::string openDirectory(const std::string &title,
const std::string &directory) const;
protected:
HWND _hwnd;
LPTSTR parseExtensions(const std::string &extensions) const;
vector<std::string> openMultipleInternal(const std::string &title,
const std::string &directory,
const std::string &extensions,
bool isMulti) const;
};
PLAYER_NS_END
#endif // __PLAYER_FILE_DIALOG_SERVICE_WIN_H_

View File

@ -0,0 +1,351 @@
#include "PlayerMenuServiceWin.h"
PLAYER_NS_BEGIN
PlayerMenuItemWin *PlayerMenuItemWin::create(const std::string &menuId, const std::string &title)
{
PlayerMenuItemWin *item = new PlayerMenuItemWin();
item->_menuId = menuId;
item->_title = title;
item->autorelease();
return item;
}
PlayerMenuItemWin::PlayerMenuItemWin()
: _parent(nullptr)
, _commandId(0)
, _hmenu(NULL)
, _menubarEnabled(true)
{
}
PlayerMenuItemWin::~PlayerMenuItemWin()
{
CC_SAFE_RELEASE(_parent);
if (_hmenu)
{
CCLOG("PlayerMenuItemWin::~PlayerMenuItemWin() - %s (HMENU)", _menuId.c_str());
DestroyMenu(_hmenu);
}
else
{
CCLOG("PlayerMenuItemWin::~PlayerMenuItemWin() - %s", _menuId.c_str());
}
}
void PlayerMenuItemWin::setTitle(const std::string &title)
{
if (title.length() == 0)
{
CCLOG("MenuServiceWin::setTitle() - can not set menu title to empty, menu id (%s)", _menuId.c_str());
return;
}
MENUITEMINFO menuitem;
menuitem.cbSize = sizeof(menuitem);
menuitem.fMask = MIIM_FTYPE | MIIM_STRING;
menuitem.fType = (title.compare("-") == 0) ? MFT_SEPARATOR : MFT_STRING;
std::u16string u16title;
cocos2d::StringUtils::UTF8ToUTF16(title, u16title);
menuitem.dwTypeData = (LPTSTR)u16title.c_str();
if (SetMenuItemInfo(_parent->_hmenu, _commandId, MF_BYCOMMAND, &menuitem))
{
_title = title;
}
else
{
DWORD err = GetLastError();
CCLOG("MenuServiceWin::setTitle() - set menu title failed, menu id (%s). error code = %u", _menuId.c_str(), err);
}
}
void PlayerMenuItemWin::setEnabled(bool enabled)
{
MENUITEMINFO menuitem = {0};
menuitem.cbSize = sizeof(menuitem);
menuitem.fMask = MIIM_STATE;
menuitem.fState = (enabled && _menubarEnabled) ? MFS_ENABLED : MFS_DISABLED;
if (SetMenuItemInfo(_parent->_hmenu, _commandId, MF_BYCOMMAND, &menuitem))
{
_isEnabled = enabled;
}
else
{
DWORD err = GetLastError();
CCLOG("MenuServiceWin::setEnabled() - set menu enabled failed, menu id (%s). error code = %u", _menuId.c_str(), err);
}
}
void PlayerMenuItemWin::setChecked(bool checked)
{
MENUITEMINFO menuitem;
menuitem.cbSize = sizeof(menuitem);
menuitem.fMask = MIIM_STATE;
menuitem.fState = (checked) ? MFS_CHECKED : MFS_UNCHECKED;
if (SetMenuItemInfo(_parent->_hmenu, _commandId, MF_BYCOMMAND, &menuitem))
{
_isChecked = checked;
}
else
{
DWORD err = GetLastError();
CCLOG("MenuServiceWin::setChecked() - set menu checked failed, menu id (%s). error code = %u", _menuId.c_str(), err);
}
}
void PlayerMenuItemWin::setShortcut(const std::string &shortcut)
{
}
// MenuServiceWin
WORD PlayerMenuServiceWin::_newCommandId = 0x1000;
PlayerMenuServiceWin::PlayerMenuServiceWin(HWND hwnd)
: _hwnd(hwnd)
, _menubarEnabled(true)
{
// create menu
_root._menuId = "__ROOT__";
_root._commandId = 0;
// hwnd has menu
HMENU menu = GetMenu(hwnd);
if (menu)
{
_root._hmenu = menu;
}
else
{
_root._hmenu = CreateMenu();
SetMenu(hwnd, _root._hmenu);
}
}
PlayerMenuServiceWin::~PlayerMenuServiceWin()
{
}
PlayerMenuItem *PlayerMenuServiceWin::addItem(const std::string &menuId,
const std::string &title,
const std::string &parentId,
int order /* = MAX_ORDER */)
{
if (menuId.length() == 0 || title.length() == 0)
{
CCLOG("MenuServiceWin::addItem() - menuId and title must is non-empty");
return nullptr;
}
// check menu id is exists
if (_items.find(menuId) != _items.end())
{
CCLOG("MenuServiceWin::addItem() - menu id (%s) is exists", menuId.c_str());
return false;
}
// set parent
PlayerMenuItemWin *parent = &_root;
if (parentId.length())
{
// query parent menu
auto it = _items.find(parentId);
if (it != _items.end())
{
parent = it->second;
}
}
if (!parent->_hmenu)
{
// create menu handle for parent (convert parent to submenu)
parent->_hmenu = CreateMenu();
parent->_isGroup = true;
MENUITEMINFO menuitem;
menuitem.cbSize = sizeof(menuitem);
menuitem.fMask = MIIM_SUBMENU;
menuitem.hSubMenu = parent->_hmenu;
if (!SetMenuItemInfo(parent->_parent->_hmenu, parent->_commandId, MF_BYCOMMAND, &menuitem))
{
DWORD err = GetLastError();
CCLOG("MenuServiceWin::addItem() - set menu handle failed, menu id (%s). error code = %u", parent->_menuId.c_str(), err);
return nullptr;
}
}
// create new menu item
_newCommandId++;
PlayerMenuItemWin *item = PlayerMenuItemWin::create(menuId, title);
item->_commandId = _newCommandId;
item->_parent = parent;
item->_parent->retain();
// add menu item to menu bar
MENUITEMINFO menuitem;
menuitem.cbSize = sizeof(menuitem);
menuitem.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STATE | MIIM_STRING;
menuitem.fType = (item->_title.compare("-") == 0) ? MFT_SEPARATOR : MFT_STRING;
menuitem.fState = (item->_isEnabled) ? MFS_ENABLED : MFS_DISABLED;
menuitem.fState |= (item->_isChecked) ? MFS_CHECKED : MFS_UNCHECKED;
std::u16string u16title;
cocos2d::StringUtils::UTF8ToUTF16(item->_title, u16title);
menuitem.dwTypeData = (LPTSTR)u16title.c_str();
menuitem.wID = _newCommandId;
// check new menu item position
if (order > parent->_children.size())
{
order = parent->_children.size();
}
else if (order < 0)
{
order = 0;
}
// create new menu item
if (!InsertMenuItem(parent->_hmenu, order, TRUE, &menuitem))
{
DWORD err = GetLastError();
CCLOG("MenuServiceWin::addItem() - insert new menu item failed, menu id (%s). error code = %u", item->_menuId.c_str(), err);
item->release();
return nullptr;
}
// update menu state
parent->_children.insert(order, item);
_items[item->_menuId] = item;
_commandId2menuId[item->_commandId] = item->_menuId;
updateChildrenOrder(parent);
return item;
}
PlayerMenuItem *PlayerMenuServiceWin::addItem(const std::string &menuId,
const std::string &title)
{
return addItem(menuId, title, "");
}
PlayerMenuItem *PlayerMenuServiceWin::getItem(const std::string &menuId)
{
auto it = _items.find(menuId);
if (it == _items.end())
{
CCLOG("MenuServiceWin::getItem() - Invalid menu id (%s)", menuId.c_str());
return nullptr;
}
return it->second;
}
bool PlayerMenuServiceWin::removeItem(const std::string &menuId)
{
return removeItemInternal(menuId, true);
}
void PlayerMenuServiceWin::setMenuBarEnabled(bool enabled)
{
_menubarEnabled = enabled;
UINT state = enabled ? MFS_ENABLED : MFS_DISABLED;
for (auto it = _root._children.begin(); it != _root._children.end(); ++it)
{
PlayerMenuItemWin *item = *it;
MENUITEMINFO menuitem = {0};
menuitem.cbSize = sizeof(menuitem);
menuitem.fMask = MIIM_STATE;
menuitem.fState = state;
SetMenuItemInfo(item->_parent->_hmenu, item->_commandId, MF_BYCOMMAND, &menuitem);
item->_menubarEnabled = enabled;
}
}
PlayerMenuItemWin *PlayerMenuServiceWin::getItemByCommandId(WORD commandId)
{
auto it = _commandId2menuId.find(commandId);
if (it == _commandId2menuId.end()) return nullptr;
return _items[it->second];
}
bool PlayerMenuServiceWin::removeItemInternal(const std::string &menuId, bool isUpdateChildrenOrder)
{
auto it = _items.find(menuId);
if (it == _items.end())
{
CCLOG("MenuServiceWin::removeItem() - Invalid menu id (%s)", menuId.c_str());
return false;
}
PlayerMenuItemWin *item = it->second;
if (item->_children.size() == 0)
{
if (!DeleteMenu(item->_parent->_hmenu, item->_commandId, MF_BYCOMMAND))
{
DWORD err = GetLastError();
CCLOG("MenuServiceWin::removeItem() - remove menu item failed, menu id (%s). error code = %u", item->_menuId.c_str(), err);
return false;
}
// remove item from parent
bool removed = false;
auto *children = &item->_parent->_children;
for (auto it = children->begin(); it != children->end(); ++it)
{
if ((*it)->_commandId == item->_commandId)
{
CCLOG("MenuServiceWin::removeItem() - remove menu item (%s)", item->_menuId.c_str());
children->erase(it);
removed = true;
break;
}
}
if (!removed)
{
CCLOG("MenuServiceWin::removeItem() - remove menu item (%s) failed, not found command id from parent->children", item->_menuId.c_str());
}
// remove menu id mapping
_items.erase(menuId);
_commandId2menuId.erase(item->_commandId);
if (isUpdateChildrenOrder)
{
updateChildrenOrder(item->_parent);
}
DrawMenuBar(_hwnd);
return true;
}
else
{
// remove all children
while (item->_children.size() != 0)
{
PlayerMenuItemWin *child = *item->_children.begin();
if (!removeItemInternal(child->_menuId.c_str(), false))
{
break;
return false;
}
}
return removeItemInternal(menuId, true);
}
return false;
}
void PlayerMenuServiceWin::updateChildrenOrder(PlayerMenuItemWin *parent)
{
auto *children = &parent->_children;
int order = 0;
for (auto it = children->begin(); it != children->end(); ++it)
{
(*it)->_order = order;
order++;
}
}
PLAYER_NS_END

View File

@ -0,0 +1,70 @@
#ifndef __PLAYER_MENU_SERVICE_WIN_H_
#define __PLAYER_MENU_SERVICE_WIN_H_
#include <string>
#include <unordered_map>
#include "cocos2d.h"
#include "stdafx.h"
#include "PlayerMenuServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerMenuItemWin : public PlayerMenuItem
{
public:
static PlayerMenuItemWin *create(const std::string &menuId, const std::string &title);
virtual ~PlayerMenuItemWin();
virtual void setTitle(const std::string &title);
virtual void setEnabled(bool enabled);
virtual void setChecked(bool checked);
virtual void setShortcut(const std::string &shortcut);
protected:
PlayerMenuItemWin();
PlayerMenuItemWin *_parent;
UINT _commandId;
HMENU _hmenu;
bool _menubarEnabled;
cocos2d::Vector<PlayerMenuItemWin*> _children;
friend class PlayerMenuServiceWin;
};
class PlayerMenuServiceWin : public PlayerMenuServiceProtocol
{
public:
PlayerMenuServiceWin(HWND hwnd);
virtual ~PlayerMenuServiceWin();
virtual PlayerMenuItem *addItem(const std::string &menuId,
const std::string &title,
const std::string &parentId,
int order = MAX_ORDER);
virtual PlayerMenuItem *addItem(const std::string &menuId,
const std::string &title);
virtual PlayerMenuItem *getItem(const std::string &menuId);
virtual bool removeItem(const std::string &menuId);
virtual void setMenuBarEnabled(bool enabled);
PlayerMenuItemWin *getItemByCommandId(WORD commandId);
private:
static WORD _newCommandId;
HWND _hwnd;
bool _menubarEnabled;
PlayerMenuItemWin _root;
std::unordered_map<std::string, PlayerMenuItemWin*> _items;
std::unordered_map<WORD, std::string> _commandId2menuId;
bool removeItemInternal(const std::string &menuId, bool isUpdateChildrenOrder);
void updateChildrenOrder(PlayerMenuItemWin *parent);
};
PLAYER_NS_END
#endif // __PLAYER_MENU_SERVICE_WIN_H_

View File

@ -0,0 +1,67 @@
#include "PlayerMessageBoxServiceWin.h"
PLAYER_NS_BEGIN
PlayerMessageBoxServiceWin::PlayerMessageBoxServiceWin(HWND hwnd)
: _hwnd(hwnd)
{
}
int PlayerMessageBoxServiceWin::showMessageBox(const std::string &title,
const std::string &message,
int buttonsType /* = BUTTONS_OK */)
{
std::u16string u16title;
cocos2d::StringUtils::UTF8ToUTF16(title, u16title);
std::u16string u16message;
cocos2d::StringUtils::UTF8ToUTF16(message, u16message);
CCLOG("PlayerMessageBoxServiceWin::showMessageBox() - title = %s, message = %s", title.c_str(), message.c_str());
UINT mbtype = MB_APPLMODAL;
switch (buttonsType)
{
case BUTTONS_OK_CANCEL:
mbtype |= MB_OKCANCEL | MB_ICONQUESTION;
break;
case BUTTONS_YES_NO:
mbtype |= MB_YESNO | MB_ICONQUESTION;
break;
case BUTTONS_YES_NO_CANCEL:
mbtype |= MB_YESNOCANCEL | MB_ICONQUESTION;
break;
default:
mbtype |= MB_OK | MB_ICONINFORMATION;
}
// MessageBox() used by cocos2d
int result = ::MessageBoxW(_hwnd, (LPCTSTR)u16message.c_str(), (LPCTSTR)u16title.c_str(), mbtype);
switch (result)
{
case IDCANCEL:
result = BUTTON_CANCEL;
break;
case IDYES:
result = BUTTON_YES;
break;
case IDNO:
result = BUTTON_NO;
break;
default:
result = BUTTON_OK;
}
CCLOG("PlayerMessageBoxServiceWin::showMessageBox() - result = %d", result);
return result;
}
PLAYER_NS_END

View File

@ -0,0 +1,28 @@
#ifndef __PLAYER_MESSAGEBOX_SERVICE_WIN_H_
#define __PLAYER_MESSAGEBOX_SERVICE_WIN_H_
#include <string>
#include "stdafx.h"
#include "cocos2d.h"
#include "PlayerMessageBoxServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerMessageBoxServiceWin : public PlayerMessageBoxServiceProtocol
{
public:
PlayerMessageBoxServiceWin(HWND hwnd);
virtual int showMessageBox(const std::string &title,
const std::string &message,
int buttonsType = BUTTONS_OK);
protected:
HWND _hwnd;
};
PLAYER_NS_END
#endif // __PLAYER_MESSAGEBOX_SERVICE_WIN_H_

View File

@ -0,0 +1,272 @@
#include <sstream>
#include "stdafx.h"
#include "shellapi.h"
#include "PlayerTaskServiceWin.h"
static const int MAX_LOG_LENGTH = 16 * 1024;// from 2dx
PLAYER_NS_BEGIN
PlayerTaskWin *PlayerTaskWin::create(const std::string &name, const std::string &executePath, const std::string &commandLineArguments)
{
PlayerTaskWin *task = new PlayerTaskWin(name, executePath, commandLineArguments);
task->autorelease();
return task;
}
PlayerTaskWin::PlayerTaskWin(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments)
: PlayerTask(name, executePath, commandLineArguments)
, _childStdInRead(NULL)
, _childStdInWrite(NULL)
, _childStdOutRead(NULL)
, _childStdOutWrite(NULL)
, _outputBuff(NULL)
, _outputBuffWide(NULL)
{
ZeroMemory(&_pi, sizeof(_pi));
}
PlayerTaskWin::~PlayerTaskWin()
{
cleanup();
}
bool PlayerTaskWin::run()
{
if (!isIdle())
{
CCLOG("PlayerTaskWin::run() - task is not idle");
return false;
}
//BOOL WINAPI CreateProcess(
// _In_opt_ LPCTSTR lpApplicationName,
// _Inout_opt_ LPTSTR lpCommandLine,
// _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
// _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
// _In_ BOOL bInheritHandles,
// _In_ DWORD dwCreationFlags,
// _In_opt_ LPVOID lpEnvironment,
// _In_opt_ LPCTSTR lpCurrentDirectory,
// _In_ LPSTARTUPINFO lpStartupInfo,
// _Out_ LPPROCESS_INFORMATION lpProcessInformation
//);
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
// Create a pipe for the child process's STDOUT.
if (!CreatePipe(&_childStdOutRead, &_childStdOutWrite, &sa, 0) || !SetHandleInformation(_childStdOutRead, HANDLE_FLAG_INHERIT, 0))
{
CCLOG("PlayerTaskWin::run() - create stdout handle failed, for execute %s", _executePath.c_str());
cleanup();
return false;
}
// Create a pipe for the child process's STDIN.
if (!CreatePipe(&_childStdInRead, &_childStdInWrite, &sa, 0) || !SetHandleInformation(_childStdInWrite, HANDLE_FLAG_INHERIT, 0))
{
CCLOG("PlayerTaskWin::run() - create stdout handle failed, for execute %s", _executePath.c_str());
cleanup();
return false;
}
ZeroMemory(&_pi, sizeof(_pi));
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
si.hStdError = _childStdOutWrite;
si.hStdOutput = _childStdOutWrite;
si.hStdInput = _childStdInRead;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
#define MAX_COMMAND 4096 //MAX_PATH
const std::u16string u16command = makeCommandLine();
WCHAR command[MAX_COMMAND];
wcscpy_s(command, MAX_COMMAND, (WCHAR*)u16command.c_str());
BOOL success = CreateProcess(NULL,
command, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&si, // STARTUPINFO pointer
&_pi); // receives PROCESS_INFORMATION
if (!success)
{
CCLOG("PlayerTaskWin::run() - create process failed, for execute %s", _executePath.c_str());
cleanup();
return false;
}
_outputBuff = new CHAR[BUFF_SIZE + 1];
_outputBuffWide = new WCHAR[BUFF_SIZE];
_state = STATE_RUNNING;
cocos2d::Director::getInstance()->getScheduler()->scheduleUpdate(this, 0, false);
return true;
}
void PlayerTaskWin::runInTerminal()
{
std::stringstream buf;
buf << "/K ";
buf << _executePath;
buf << " ";
buf << _commandLineArguments;
std::u16string u16command;
cocos2d::StringUtils::UTF8ToUTF16(buf.str(), u16command);
ShellExecute(NULL, NULL, L"CMD.EXE", (WCHAR*)u16command.c_str(), NULL, SW_SHOWNORMAL);
}
void PlayerTaskWin::stop()
{
if (_pi.hProcess)
{
TerminateProcess(_pi.hProcess, 0);
_resultCode = -1;
}
cleanup();
}
void PlayerTaskWin::update(float dt)
{
_lifetime += dt;
// read output
for (;;)
{
DWORD readCount = 0;
PeekNamedPipe(_childStdOutRead, NULL, NULL, NULL, &readCount, NULL);
if (readCount == 0) break;
if (_output.length() > MAX_LOG_LENGTH) break;
readCount = 0;
ZeroMemory(_outputBuff, BUFF_SIZE + 1);
BOOL success = ReadFile(_childStdOutRead, _outputBuff, BUFF_SIZE - 1, &readCount, NULL);
if (!success || readCount == 0) break;
int chars = MultiByteToWideChar(CP_OEMCP, 0, _outputBuff, readCount, _outputBuffWide, BUFF_SIZE);
if (chars)
{
ZeroMemory(_outputBuff, BUFF_SIZE + 1);
WideCharToMultiByte(CP_UTF8, 0, _outputBuffWide, chars, _outputBuff, BUFF_SIZE + 1, 0, NULL);
_output.append(_outputBuff);
if (_output.length() > MAX_LOG_LENGTH) break;
}
}
// get child process exit code
DWORD resultCode = 0;
if (GetExitCodeProcess(_pi.hProcess, &resultCode))
{
if (resultCode == STILL_ACTIVE) return;
_resultCode = (int)resultCode;
}
else
{
// unexpected error
_resultCode = (int)GetLastError();
}
cocos2d::Director::getInstance()->getScheduler()->unscheduleAllForTarget(this);
cleanup();
}
void PlayerTaskWin::cleanup()
{
if (_pi.hProcess) CloseHandle(_pi.hProcess);
if (_pi.hThread) CloseHandle(_pi.hThread);
ZeroMemory(&_pi, sizeof(_pi));
if (_outputBuff) delete[] _outputBuff;
_outputBuff = NULL;
if (_outputBuffWide) delete[] _outputBuffWide;
_outputBuffWide = NULL;
if (_childStdOutRead) CloseHandle(_childStdOutRead);
if (_childStdOutWrite) CloseHandle(_childStdOutWrite);
if (_childStdInRead) CloseHandle(_childStdInRead);
if (_childStdInWrite) CloseHandle(_childStdInWrite);
_childStdOutRead = NULL;
_childStdOutWrite = NULL;
_childStdInRead = NULL;
_childStdInWrite = NULL;
_state = STATE_COMPLETED;
CCLOG("CMD: %s", _output.c_str());
cocos2d::Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(_name);
}
std::u16string PlayerTaskWin::makeCommandLine() const
{
std::stringstream buf;
buf << "\"";
buf << _executePath;
buf << "\" ";
buf << _commandLineArguments;
std::u16string u16command;
cocos2d::StringUtils::UTF8ToUTF16(buf.str(), u16command);
return u16command;
}
PlayerTaskServiceWin::PlayerTaskServiceWin(HWND hwnd)
: _hwnd(hwnd)
{
}
PlayerTaskServiceWin::~PlayerTaskServiceWin()
{
for (auto it = _tasks.begin(); it != _tasks.end(); ++it)
{
it->second->stop();
}
}
PlayerTask *PlayerTaskServiceWin::createTask(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments)
{
CCASSERT(_tasks.find(name) == _tasks.end(), "Task already exists.");
PlayerTaskWin *task = PlayerTaskWin::create(name, executePath, commandLineArguments);
_tasks.insert(name, task);
return task;
}
PlayerTask *PlayerTaskServiceWin::getTask(const std::string &name)
{
auto it = _tasks.find(name);
return it != _tasks.end() ? it->second : nullptr;
}
void PlayerTaskServiceWin::removeTask(const std::string &name)
{
auto it = _tasks.find(name);
if (it != _tasks.end())
{
if (!it->second->isCompleted())
{
it->second->stop();
}
_tasks.erase(it);
}
}
PLAYER_NS_END

View File

@ -0,0 +1,65 @@
#ifndef __PLAYER_TASK_SERVICE_WIN_H_
#define __PLAYER_TASK_SERVICE_WIN_H_
#include <sstream>
#include "PlayerTaskServiceProtocol.h"
PLAYER_NS_BEGIN
class PlayerTaskWin : public PlayerTask
{
public:
static PlayerTaskWin *create(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments);
virtual ~PlayerTaskWin();
virtual bool run();
virtual void stop();
virtual void runInTerminal();
// check task status
virtual void update(float dt);
protected:
PlayerTaskWin(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments);
void cleanup();
std::u16string makeCommandLine() const;
HANDLE _childStdInRead;
HANDLE _childStdInWrite;
HANDLE _childStdOutRead;
HANDLE _childStdOutWrite;
PROCESS_INFORMATION _pi;
static const size_t BUFF_SIZE = 4096;
CHAR *_outputBuff;
WCHAR *_outputBuffWide;
};
class PlayerTaskServiceWin : public PlayerTaskServiceProtocol
{
public:
PlayerTaskServiceWin(HWND hwnd);
virtual ~PlayerTaskServiceWin();
virtual PlayerTask *createTask(const std::string &name,
const std::string &executePath,
const std::string &commandLineArguments);
virtual PlayerTask *getTask(const std::string &name);
virtual void removeTask(const std::string &name);
protected:
HWND _hwnd;
cocos2d::Map<std::string, PlayerTaskWin*> _tasks;
};
PLAYER_NS_END
#endif // __PLAYER_TASK_SERVICE_WIN_H_

View File

@ -0,0 +1,863 @@

#pragma comment(lib, "comctl32.lib")
#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include "stdafx.h"
#include <io.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include <fcntl.h>
#include <Commdlg.h>
#include <Shlobj.h>
#include <winnls.h>
#include <shobjidl.h>
#include <objbase.h>
#include <objidl.h>
#include <shlguid.h>
#include <shellapi.h>
#include "PlayerWin.h"
#include "glfw3.h"
#include "glfw3native.h"
#include "CCLuaEngine.h"
#include "AppEvent.h"
#include "AppLang.h"
#include "ConfigParser.h"
USING_NS_CC;
static WNDPROC g_oldWindowProc = NULL;
INT_PTR CALLBACK AboutDialogCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
void onHelpAbout()
{
DialogBox(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDD_DIALOG_ABOUT),
Director::getInstance()->getOpenGLView()->getWin32Window(),
AboutDialogCallback);
}
void shutDownApp()
{
auto glview = dynamic_cast<GLViewImpl*> (Director::getInstance()->getOpenGLView());
HWND hWnd = glview->getWin32Window();
::SendMessage(hWnd, WM_CLOSE, NULL, NULL);
}
std::string getCurAppPath(void)
{
TCHAR szAppDir[MAX_PATH] = { 0 };
if (!GetModuleFileName(NULL, szAppDir, MAX_PATH))
return "";
int nEnd = 0;
for (int i = 0; szAppDir[i]; i++)
{
if (szAppDir[i] == '\\')
nEnd = i;
}
szAppDir[nEnd] = 0;
int iLen = 2 * wcslen(szAppDir);
char* chRtn = new char[iLen + 1];
wcstombs(chRtn, szAppDir, iLen + 1);
std::string strPath = chRtn;
delete[] chRtn;
chRtn = NULL;
char fuldir[MAX_PATH] = { 0 };
_fullpath(fuldir, strPath.c_str(), MAX_PATH);
return fuldir;
}
PLAYER_NS_BEGIN
PlayerWin *PlayerWin::_instance = nullptr;
PlayerWin::PlayerWin()
: _app(nullptr)
, _hwnd(NULL)
, _hwndConsole(NULL)
, _writeDebugLogFile(nullptr)
, _messageBoxService(nullptr)
, _menuService(nullptr)
, _editboxService(nullptr)
, _taskService(nullptr)
{
}
PlayerWin::~PlayerWin()
{
CC_SAFE_DELETE(_menuService);
CC_SAFE_DELETE(_messageBoxService);
CC_SAFE_DELETE(_fileDialogService);
CC_SAFE_DELETE(_app);
if (_writeDebugLogFile)
{
fclose(_writeDebugLogFile);
}
_instance = nullptr;
}
PlayerWin *PlayerWin::getInstance()
{
if (!_instance)
{
_instance = new PlayerWin();
}
return _instance;
}
PlayerFileDialogServiceProtocol *PlayerWin::getFileDialogService()
{
return _fileDialogService;
}
PlayerMessageBoxServiceProtocol *PlayerWin::getMessageBoxService()
{
return _messageBoxService;
}
PlayerMenuServiceProtocol *PlayerWin::getMenuService()
{
return _menuService;
}
PlayerEditBoxServiceProtocol *PlayerWin::getEditBoxService()
{
return _editboxService;
}
PlayerTaskServiceProtocol *PlayerWin::getTaskService()
{
return _taskService;
}
void PlayerWin::quit()
{
Director::getInstance()->end();
}
void PlayerWin::relaunch()
{
_project.setWindowOffset(Vec2(getPositionX(), getPositionY()));
openNewPlayerWithProjectConfig(_project);
quit();
}
void PlayerWin::openNewPlayer()
{
openNewPlayerWithProjectConfig(_project);
}
void PlayerWin::openNewPlayerWithProjectConfig(const ProjectConfig &config)
{
static long taskid = 100;
stringstream buf;
buf << taskid++;
string commandLine;
commandLine.append(getApplicationExePath());
commandLine.append(" ");
commandLine.append(config.makeCommandLine());
CCLOG("PlayerWin::openNewPlayerWithProjectConfig(): %s", commandLine.c_str());
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
#define MAX_COMMAND 1024 // lenth of commandLine is always beyond MAX_PATH
WCHAR command[MAX_COMMAND];
memset(command, 0, sizeof(command));
MultiByteToWideChar(CP_UTF8, 0, commandLine.c_str(), -1, command, MAX_COMMAND);
BOOL success = CreateProcess(NULL,
command, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
FALSE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&si, // STARTUPINFO pointer
&pi); // receives PROCESS_INFORMATION
if (!success)
{
CCLOG("PlayerTaskWin::run() - create process failed, for execute %s", commandLine.c_str());
}
}
void PlayerWin::openProjectWithProjectConfig(const ProjectConfig &config)
{
openNewPlayerWithProjectConfig(config);
quit();
}
int PlayerWin::getPositionX()
{
RECT rect;
GetWindowRect(_hwnd, &rect);
return rect.left;
}
int PlayerWin::getPositionY()
{
RECT rect;
GetWindowRect(_hwnd, &rect);
return rect.top;
}
int PlayerWin::run()
{
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
parseCocosProjectConfig(_project);
// load project config from command line args
vector<string> args;
for (int i = 0; i < __argc; ++i)
{
wstring ws(__wargv[i]);
string s;
s.assign(ws.begin(), ws.end());
args.push_back(s);
}
_project.parseCommandLine(args);
if (_project.getProjectDir().empty())
{
if (args.size() == 2)
{
// for Code IDE before RC2
_project.setProjectDir(args.at(1));
_project.setDebuggerType(kCCRuntimeDebuggerCodeIDE);
}
}
// create the application instance
_app = new AppDelegate();
_app->setProjectConfig(_project);
// create console window
if (_project.isShowConsole())
{
AllocConsole();
_hwndConsole = GetConsoleWindow();
if (_hwndConsole != NULL)
{
ShowWindow(_hwndConsole, SW_SHOW);
BringWindowToTop(_hwndConsole);
freopen("CONOUT$", "wt", stdout);
freopen("CONOUT$", "wt", stderr);
HMENU hmenu = GetSystemMenu(_hwndConsole, FALSE);
if (hmenu != NULL)
{
DeleteMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
}
}
}
// log file
if (_project.isWriteDebugLogToFile())
{
const string debugLogFilePath = _project.getDebugLogFilePath();
_writeDebugLogFile = fopen(debugLogFilePath.c_str(), "w");
if (!_writeDebugLogFile)
{
CCLOG("Cannot create debug log file %s", debugLogFilePath.c_str());
}
}
// set environments
SetCurrentDirectoryA(_project.getProjectDir().c_str());
FileUtils::getInstance()->setDefaultResourceRootPath(_project.getProjectDir());
FileUtils::getInstance()->setWritablePath(_project.getWritableRealPath().c_str());
// check screen DPI
HDC screen = GetDC(0);
int dpi = GetDeviceCaps(screen, LOGPIXELSX);
ReleaseDC(0, screen);
// set scale with DPI
// 96 DPI = 100 % scaling
// 120 DPI = 125 % scaling
// 144 DPI = 150 % scaling
// 192 DPI = 200 % scaling
// http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor
//
// enable DPI-Aware with DeclareDPIAware.manifest
// http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#declaring_dpi_awareness
float screenScale = 1.0f;
if (dpi >= 120 && dpi < 144)
{
screenScale = 1.25f;
}
else if (dpi >= 144 && dpi < 192)
{
screenScale = 1.5f;
}
else if (dpi >= 192)
{
screenScale = 2.0f;
}
CCLOG("SCREEN DPI = %d, SCREEN SCALE = %0.2f", dpi, screenScale);
// create opengl view
Size frameSize = _project.getFrameSize();
float frameScale = 1.0f;
if (_project.isRetinaDisplay())
{
frameSize.width *= screenScale;
frameSize.height *= screenScale;
}
else
{
frameScale = screenScale;
}
const Rect frameRect = Rect(0, 0, frameSize.width, frameSize.height);
const bool isResize = _project.isResizeWindow();
std::stringstream title;
title << "Cocos Simulator - " << ConfigParser::getInstance()->getInitViewName();
auto glview = GLViewImpl::createWithRect(title.str(), frameRect, frameScale);
_hwnd = glview->getWin32Window();
DragAcceptFiles(_hwnd, TRUE);
//SendMessage(_hwnd, WM_SETICON, ICON_BIG, (LPARAM)icon);
//SendMessage(_hwnd, WM_SETICON, ICON_SMALL, (LPARAM)icon);
//FreeResource(icon);
auto director = Director::getInstance();
director->setOpenGLView(glview);
director->setAnimationInterval(1.0 / 60.0);
// set window position
if (_project.getProjectDir().length())
{
setZoom(_project.getFrameScale());
}
Vec2 pos = _project.getWindowOffset();
if (pos.x != 0 && pos.y != 0)
{
RECT rect;
GetWindowRect(_hwnd, &rect);
MoveWindow(_hwnd, pos.x, pos.y, rect.right - rect.left, rect.bottom - rect.top, FALSE);
}
// register event handlers
auto eventDispatcher = director->getEventDispatcher();
eventDispatcher->addCustomEventListener("APP.VIEW_SCALE", CC_CALLBACK_1(PlayerWin::onWindowScale, this));
// path for looking Lang file, Studio Default images
FileUtils::getInstance()->addSearchPath(getApplicationPath().c_str());
// init player services
initServices();
setupUI();
DrawMenuBar(_hwnd);
// prepare
FileUtils::getInstance()->setPopupNotify(false);
_project.dump();
auto app = Application::getInstance();
g_oldWindowProc = (WNDPROC)SetWindowLong(_hwnd, GWL_WNDPROC, (LONG)PlayerWin::windowProc);
// update window size
RECT rect;
GetWindowRect(_hwnd, &rect);
MoveWindow(_hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + GetSystemMetrics(SM_CYMENU), FALSE);
// startup message loop
return app->run();
}
// services
void PlayerWin::initServices()
{
CCASSERT(_menuService == nullptr, "CAN'T INITIALIZATION SERVICES MORE THAN ONCE");
_menuService = new PlayerMenuServiceWin(_hwnd);
_messageBoxService = new PlayerMessageBoxServiceWin(_hwnd);
_fileDialogService = new PlayerFileDialogServiceWin(_hwnd);
_editboxService = new PlayerEditBoxServiceWin(_hwnd);
_taskService = new PlayerTaskServiceWin(_hwnd);
if (!_project.isAppMenu())
{
// remove menu
SetMenu(_hwnd, NULL);
}
}
void PlayerWin::onWindowScale(EventCustom* event)
{
//float scale = atof(event->getDataString().c_str());
//setZoom(scale);
//if (_project.isAppMenu() && GetMenu(_hwnd))
//{
// // update window size
// RECT rect;
// GetWindowRect(_hwnd, &rect);
// MoveWindow(_hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + GetSystemMetrics(SM_CYMENU), FALSE);
//}
}
void PlayerWin::setupUI()
{
auto menuBar = player::PlayerProtocol::getInstance()->getMenuService();
// FILE
menuBar->addItem("FILE_MENU", tr("File"));
menuBar->addItem("EXIT_MENU", tr("Exit"), "FILE_MENU");
// VIEW
menuBar->addItem("VIEW_MENU", tr("View"));
SimulatorConfig *config = SimulatorConfig::getInstance();
int current = config->checkScreenSize(_project.getFrameSize());
for (int i = 0; i < config->getScreenSizeCount(); i++)
{
SimulatorScreenSize size = config->getScreenSize(i);
std::stringstream menuId;
menuId << "VIEWSIZE_ITEM_MENU_" << i;
auto menuItem = menuBar->addItem(menuId.str(), size.title.c_str(), "VIEW_MENU");
if (i == current)
{
menuItem->setChecked(true);
}
}
menuBar->addItem("DIRECTION_MENU_SEP", "-", "VIEW_MENU");
menuBar->addItem("DIRECTION_PORTRAIT_MENU", tr("Portrait"), "VIEW_MENU")
->setChecked(_project.isPortraitFrame());
menuBar->addItem("DIRECTION_LANDSCAPE_MENU", tr("Landscape"), "VIEW_MENU")
->setChecked(_project.isLandscapeFrame());
menuBar->addItem("VIEW_SCALE_MENU_SEP", "-", "VIEW_MENU");
std::vector<player::PlayerMenuItem*> scaleMenuVector;
auto scale100Menu = menuBar->addItem("VIEW_SCALE_MENU_100", tr("Zoom Out").append(" (100%)"), "VIEW_MENU");
auto scale75Menu = menuBar->addItem("VIEW_SCALE_MENU_75", tr("Zoom Out").append(" (75%)"), "VIEW_MENU");
auto scale50Menu = menuBar->addItem("VIEW_SCALE_MENU_50", tr("Zoom Out").append(" (50%)"), "VIEW_MENU");
auto scale25Menu = menuBar->addItem("VIEW_SCALE_MENU_25", tr("Zoom Out").append(" (25%)"), "VIEW_MENU");
int frameScale = int(_project.getFrameScale() * 100);
if (frameScale == 100)
{
scale100Menu->setChecked(true);
}
else if (frameScale == 75)
{
scale75Menu->setChecked(true);
}
else if (frameScale == 50)
{
scale50Menu->setChecked(true);
}
else if (frameScale == 25)
{
scale25Menu->setChecked(true);
}
else
{
scale100Menu->setChecked(true);
}
scaleMenuVector.push_back(scale100Menu);
scaleMenuVector.push_back(scale75Menu);
scaleMenuVector.push_back(scale50Menu);
scaleMenuVector.push_back(scale25Menu);
menuBar->addItem("REFRESH_MENU_SEP", "-", "VIEW_MENU");
menuBar->addItem("REFRESH_MENU", tr("Refresh"), "VIEW_MENU");
HWND &hwnd = _hwnd;
ProjectConfig &project = _project;
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->addEventListenerWithFixedPriority(EventListenerCustom::create("APP.EVENT", [&project, &hwnd, scaleMenuVector](EventCustom* event){
auto menuEvent = dynamic_cast<AppEvent*>(event);
if (menuEvent)
{
rapidjson::Document dArgParse;
dArgParse.Parse<0>(menuEvent->getDataString().c_str());
if (dArgParse.HasMember("name"))
{
string strcmd = dArgParse["name"].GetString();
if (strcmd == "menuClicked")
{
player::PlayerMenuItem *menuItem = static_cast<player::PlayerMenuItem*>(menuEvent->getUserData());
if (menuItem)
{
if (menuItem->isChecked())
{
return;
}
string data = dArgParse["data"].GetString();
auto player = player::PlayerProtocol::getInstance();
if ((data == "CLOSE_MENU") || (data == "EXIT_MENU"))
{
player->quit();
}
else if (data == "REFRESH_MENU")
{
player->relaunch();
}
else if (data.find("VIEW_SCALE_MENU_") == 0) // begin with VIEW_SCALE_MENU_
{
string tmp = data.erase(0, strlen("VIEW_SCALE_MENU_"));
float scale = atof(tmp.c_str()) / 100.0f;
project.setFrameScale(scale);
auto glview = static_cast<GLViewImpl*>(Director::getInstance()->getOpenGLView());
glview->setFrameZoomFactor(scale);
// update scale menu state
for (auto &it : scaleMenuVector)
{
it->setChecked(false);
}
menuItem->setChecked(true);
// update window size
RECT rect;
GetWindowRect(hwnd, &rect);
MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + GetSystemMetrics(SM_CYMENU), FALSE);
// fix: can not update window on some windows system
::SendMessage(hwnd, WM_MOVE, NULL, NULL);
}
else if (data.find("VIEWSIZE_ITEM_MENU_") == 0) // begin with VIEWSIZE_ITEM_MENU_
{
string tmp = data.erase(0, strlen("VIEWSIZE_ITEM_MENU_"));
int index = atoi(tmp.c_str());
SimulatorScreenSize size = SimulatorConfig::getInstance()->getScreenSize(index);
if (project.isLandscapeFrame())
{
std::swap(size.width, size.height);
}
project.setFrameSize(cocos2d::Size(size.width, size.height));
project.setWindowOffset(cocos2d::Vec2(player->getPositionX(), player->getPositionY()));
player->openProjectWithProjectConfig(project);
}
else if (data == "DIRECTION_PORTRAIT_MENU")
{
project.changeFrameOrientationToPortait();
player->openProjectWithProjectConfig(project);
}
else if (data == "DIRECTION_LANDSCAPE_MENU")
{
project.changeFrameOrientationToLandscape();
player->openProjectWithProjectConfig(project);
}
}
}
}
}
}), 1);
AppDelegate *app = _app;
auto listener = EventListenerCustom::create(kAppEventDropName, [&project, app](EventCustom* event)
{
AppEvent *dropEvent = dynamic_cast<AppEvent*>(event);
if (dropEvent)
{
string dirPath = dropEvent->getDataString() + "/";
string configFilePath = dirPath + CONFIG_FILE;
if (FileUtils::getInstance()->isDirectoryExist(dirPath) &&
FileUtils::getInstance()->isFileExist(configFilePath))
{
// parse config.json
ConfigParser::getInstance()->readConfig(configFilePath);
project.setProjectDir(dirPath);
project.setScriptFile(ConfigParser::getInstance()->getEntryFile());
project.setWritablePath(dirPath);
app->setProjectConfig(project);
app->reopenProject();
}
}
});
dispatcher->addEventListenerWithFixedPriority(listener, 1);
}
void PlayerWin::setZoom(float frameScale)
{
_project.setFrameScale(frameScale);
cocos2d::Director::getInstance()->getOpenGLView()->setFrameZoomFactor(frameScale);
}
// debug log
void PlayerWin::writeDebugLog(const char *log)
{
if (!_writeDebugLogFile) return;
fputs(log, _writeDebugLogFile);
fputc('\n', _writeDebugLogFile);
fflush(_writeDebugLogFile);
}
void PlayerWin::parseCocosProjectConfig(ProjectConfig &config)
{
// get project directory
ProjectConfig tmpConfig;
// load project config from command line args
vector<string> args;
for (int i = 0; i < __argc; ++i)
{
wstring ws(__wargv[i]);
string s;
s.assign(ws.begin(), ws.end());
args.push_back(s);
}
if (args.size() >= 2)
{
if (args.size() && args.at(1).at(0) == '/')
{
// FIXME:
// for Code IDE before RC2
tmpConfig.setProjectDir(args.at(1));
}
tmpConfig.parseCommandLine(args);
}
// set project directory as search root path
FileUtils::getInstance()->setDefaultResourceRootPath(tmpConfig.getProjectDir().c_str());
// parse config.json
auto parser = ConfigParser::getInstance();
auto configPath = tmpConfig.getProjectDir().append(CONFIG_FILE);
parser->readConfig(configPath);
// set information
config.setConsolePort(parser->getConsolePort());
config.setFileUploadPort(parser->getUploadPort());
config.setFrameSize(parser->getInitViewSize());
if (parser->isLanscape())
{
config.changeFrameOrientationToLandscape();
}
config.setScriptFile(parser->getEntryFile());
}
//
// D:\aaa\bbb\ccc\ddd\abc.txt --> D:/aaa/bbb/ccc/ddd/abc.txt
//
std::string PlayerWin::convertPathFormatToUnixStyle(const std::string& path)
{
std::string ret = path;
int len = ret.length();
for (int i = 0; i < len; ++i)
{
if (ret[i] == '\\')
{
ret[i] = '/';
}
}
return ret;
}
//
// @return: C:/Users/win8/Documents/
//
std::string PlayerWin::getUserDocumentPath()
{
TCHAR filePath[MAX_PATH];
SHGetSpecialFolderPath(NULL, filePath, CSIDL_PERSONAL, FALSE);
int length = 2 * wcslen(filePath);
char* tempstring = new char[length + 1];
wcstombs(tempstring, filePath, length + 1);
string userDocumentPath(tempstring);
free(tempstring);
userDocumentPath = convertPathFormatToUnixStyle(userDocumentPath);
userDocumentPath.append("/");
return userDocumentPath;
}
//
// convert Unicode/LocalCode TCHAR to Utf8 char
//
char* PlayerWin::convertTCharToUtf8(const TCHAR* src)
{
#ifdef UNICODE
WCHAR* tmp = (WCHAR*)src;
size_t size = wcslen(src) * 3 + 1;
char* dest = new char[size];
memset(dest, 0, size);
WideCharToMultiByte(CP_UTF8, 0, tmp, -1, dest, size, NULL, NULL);
return dest;
#else
char* tmp = (char*)src;
uint32 size = strlen(tmp) + 1;
WCHAR* dest = new WCHAR[size];
memset(dest, 0, sizeof(WCHAR)*size);
MultiByteToWideChar(CP_ACP, 0, src, -1, dest, (int)size); // convert local code to unicode.
size = wcslen(dest) * 3 + 1;
char* dest2 = new char[size];
memset(dest2, 0, size);
WideCharToMultiByte(CP_UTF8, 0, dest, -1, dest2, size, NULL, NULL); // convert unicode to utf8.
delete[] dest;
return dest2;
#endif
}
//
std::string PlayerWin::getApplicationExePath()
{
TCHAR szFileName[MAX_PATH];
GetModuleFileName(NULL, szFileName, MAX_PATH);
std::u16string u16ApplicationName;
char *applicationExePath = convertTCharToUtf8(szFileName);
std::string path(applicationExePath);
CC_SAFE_FREE(applicationExePath);
return path;
}
std::string PlayerWin::getApplicationPath()
{
std::string path = getApplicationExePath();
size_t pos;
while ((pos = path.find_first_of("\\")) != std::string::npos)
{
path.replace(pos, 1, "/");
}
size_t p = path.find_last_of("/");
string workdir;
if (p != path.npos)
{
workdir = path.substr(0, p);
}
return workdir;
}
LRESULT CALLBACK PlayerWin::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (!_instance) return 0;
switch (uMsg)
{
case WM_COMMAND:
{
if (HIWORD(wParam) == 0)
{
// menu
WORD menuId = LOWORD(wParam);
PlayerMenuItemWin *menuItem = _instance->_menuService->getItemByCommandId(menuId);
if (menuItem)
{
AppEvent event("APP.EVENT", APP_EVENT_MENU);
std::stringstream buf;
buf << "{\"data\":\"" << menuItem->getMenuId().c_str() << "\"";
buf << ",\"name\":" << "\"menuClicked\"" << "}";
event.setDataString(buf.str());
event.setUserData(menuItem);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
if (menuId == ID_HELP_ABOUT)
{
onHelpAbout();
}
}
break;
}
case WM_KEYDOWN:
{
if (wParam == VK_F5)
{
PlayerProtocol::getInstance()->relaunch();
}
break;
}
case WM_COPYDATA:
{
PCOPYDATASTRUCT pMyCDS = (PCOPYDATASTRUCT) lParam;
if (pMyCDS->dwData == 1)
{
const char *szBuf = (const char*)(pMyCDS->lpData);
PlayerWin::getInstance()->writeDebugLog(szBuf);
break;
}
}
case WM_DESTROY:
{
DragAcceptFiles(hWnd, FALSE);
break;
}
case WM_DROPFILES:
{
HDROP hDrop = (HDROP)wParam;
const int count = DragQueryFileW(hDrop, 0xffffffff, NULL, 0);
if (count > 0)
{
int fileIndex = 0;
const UINT length = DragQueryFileW(hDrop, fileIndex, NULL, 0);
WCHAR* buffer = (WCHAR*)calloc(length + 1, sizeof(WCHAR));
DragQueryFileW(hDrop, fileIndex, buffer, length + 1);
char *utf8 = PlayerWin::convertTCharToUtf8(buffer);
std::string firstFile(utf8);
CC_SAFE_FREE(utf8);
DragFinish(hDrop);
// broadcast drop event
AppEvent forwardEvent("APP.EVENT.DROP", APP_EVENT_DROP);
forwardEvent.setDataString(firstFile);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&forwardEvent);
}
} // WM_DROPFILES
}
return g_oldWindowProc(hWnd, uMsg, wParam, lParam);
}
PLAYER_NS_END

View File

@ -0,0 +1,82 @@
#pragma once
#include "stdafx.h"
#include "Resource.h"
#include "cocos2d.h"
#include "AppDelegate.h"
#include "ProjectConfig/ProjectConfig.h"
#include "ProjectConfig/SimulatorConfig.h"
#include "PlayerMacros.h"
#include "PlayerProtocol.h"
#include "PlayerMenuServiceWin.h"
#include "PlayerMessageBoxServiceWin.h"
#include "PlayerFileDialogServiceWin.h"
#include "PlayerEditBoxServiceWin.h"
#include "PlayerTaskServiceWin.h"
PLAYER_NS_BEGIN
class PlayerWin : public PlayerProtocol, public cocos2d::Ref
{
public:
static PlayerWin *getInstance();
virtual ~PlayerWin();
int run();
virtual PlayerFileDialogServiceProtocol *getFileDialogService();
virtual PlayerMessageBoxServiceProtocol *getMessageBoxService();
virtual PlayerMenuServiceProtocol *getMenuService();
virtual PlayerEditBoxServiceProtocol *getEditBoxService();
virtual PlayerTaskServiceProtocol *getTaskService();
virtual void quit();
virtual void relaunch();
virtual void openNewPlayer();
virtual void openNewPlayerWithProjectConfig(const ProjectConfig &config);
virtual void openProjectWithProjectConfig(const ProjectConfig &config);
virtual int getPositionX();
virtual int getPositionY();
protected:
PlayerWin();
static PlayerWin *_instance;
ProjectConfig _project;
HWND _hwnd;
HWND _hwndConsole;
AppDelegate *_app;
FILE *_writeDebugLogFile;
PlayerMenuServiceWin *_menuService;
PlayerMessageBoxServiceWin *_messageBoxService;
PlayerFileDialogServiceWin *_fileDialogService;
PlayerEditBoxServiceWin *_editboxService;
PlayerTaskServiceWin *_taskService;
// services
void initServices();
// event handlers
void onWindowScale(cocos2d::EventCustom* event);
//
void setupUI();
void setZoom(float frameScale);
// debug log
void writeDebugLog(const char *log);
void parseCocosProjectConfig(ProjectConfig &config);
// helper
std::string convertPathFormatToUnixStyle(const std::string& path);
std::string getUserDocumentPath();
std::string getApplicationExePath();
std::string getApplicationPath();
static char* convertTCharToUtf8(const TCHAR* src);
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
PLAYER_NS_END

View File

@ -0,0 +1,38 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by game.rc
//
#define IDS_PROJNAME 100
#define IDR_TESTLUA 100
#define IDR_MENU_COCOS 201
#define IDD_DIALOG1 202
#define IDD_DIALOG_ABOUT 202
#define IDC_EDIT2 1001
#define ID_VIEW_SIZE 30001
#define ID_FILE_NEW_WINDOW 32771
#define ID_VIEW_PORTRAIT 32775
#define ID_VIEW_LANDSCAPE 32776
#define ID_VIEW_CUSTOM 32777
#define ID_HELP_ABOUT 32778
#define ID_FILE_EXIT 32779
#define ID_Menu 32780
#define ID_Menu32781 32781
#define ID_TEST_RESET 32782
#define ID_CONTROL 32783
#define ID_CONTROL_RELOAD 32784
#define ID_VIEW_ZOOMOUT100 32785
#define ID_VIEW_ZOOMOUT75 32786
#define ID_VIEW_ZOOMOUT50 32787
#define ID_VIEW_ZOOMOUT25 32788
#define ID_CONTROL_TOP 32793
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 204
#define _APS_NEXT_COMMAND_VALUE 32794
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// player.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,21 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

View File

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>