mirror of https://github.com/axmolengine/axmol.git
add new lua runtime
This commit is contained in:
parent
f01cc596a3
commit
4280ffcf58
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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_
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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_
|
|
@ -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_ */
|
|
@ -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": "缩放"
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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_
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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__) */
|
|
@ -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;
|
||||
}
|
|
@ -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__) */
|
|
@ -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
|
|
@ -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_
|
|
@ -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_
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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_
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
#include "PlayerServiceProtocol.h"
|
||||
|
||||
PLAYER_NS_BEGIN
|
||||
|
||||
PLAYER_NS_END
|
|
@ -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_
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
#include "PlayerSettings.h"
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
#include "PlayerUtils.h"
|
|
@ -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_
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
|
@ -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 generated—usually the
|
||||
// Ethernet hardware address—and 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
|
|
@ -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>
|
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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_ */
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
Loading…
Reference in New Issue