From 4280ffcf585ab32455fb077cdd4313cd29e1a52c Mon Sep 17 00:00:00 2001 From: yinjimmy Date: Sat, 27 Dec 2014 02:21:55 +0800 Subject: [PATCH] add new lua runtime --- .../runtime-src/Classes/AppDelegate.cpp | 332 ++++++- .../runtime-src/Classes/AppDelegate.h | 38 + .../runtime-src/Classes/ConfigParser.cpp | 59 +- .../runtime-src/Classes/ConfigParser.h | 26 +- .../Classes/ProjectConfig/ProjectConfig.cpp | 791 ++++++++++++++++ .../Classes/ProjectConfig/ProjectConfig.h | 148 +++ .../Classes/ProjectConfig/SimulatorConfig.cpp | 77 ++ .../Classes/ProjectConfig/SimulatorConfig.h | 57 ++ .../runtime-src/Classes/cocos2dx_extra.h | 15 + .../frameworks/runtime-src/Classes/lang | 20 + .../Classes/network/CCHTTPRequest.cpp | 554 +++++++++++ .../Classes/network/CCHTTPRequest.h | 226 +++++ .../Classes/network/CCHTTPRequestDelegate.h | 20 + .../Classes/runtime/ConsoleCommand.cpp | 31 +- .../Classes/runtime/FileServer.cpp | 12 + .../runtime-src/Classes/runtime/Runtime.cpp | 74 +- .../runtime-src/Classes/runtime/Runtime.h | 9 +- .../runtime-src/Classes/service/AppEvent.cpp | 33 + .../runtime-src/Classes/service/AppEvent.h | 47 + .../runtime-src/Classes/service/AppLang.cpp | 75 ++ .../runtime-src/Classes/service/AppLang.h | 33 + .../runtime-src/Classes/service/DeviceEx.h | 26 + .../service/PlayerEditBoxServiceProtocol.h | 37 + .../service/PlayerFileDialogServiceProtocol.h | 33 + .../Classes/service/PlayerMacros.h | 9 + .../service/PlayerMenuServiceProtocol.cpp | 53 ++ .../service/PlayerMenuServiceProtocol.h | 66 ++ .../service/PlayerMessageBoxServiceProtocol.h | 35 + .../Classes/service/PlayerProtocol.cpp | 42 + .../Classes/service/PlayerProtocol.h | 58 ++ .../Classes/service/PlayerServiceProtocol.cpp | 6 + .../Classes/service/PlayerServiceProtocol.h | 17 + .../Classes/service/PlayerSettings.cpp | 2 + .../Classes/service/PlayerSettings.h | 25 + .../service/PlayerTaskServiceProtocol.cpp | 68 ++ .../service/PlayerTaskServiceProtocol.h | 63 ++ .../Classes/service/PlayerUtils.cpp | 2 + .../runtime-src/Classes/service/PlayerUtils.h | 36 + .../runtime-src/proj.android/jni/Android.mk | 3 + .../HelloLua.xcodeproj/project.pbxproj | 235 ++++- .../proj.ios_mac/Runtime_ios-mac.mm | 10 + .../proj.ios_mac/mac/Base.lproj/MainMenu.xib | 201 ++++ .../proj.ios_mac/mac/SimulatorApp.h | 34 +- .../proj.ios_mac/mac/SimulatorApp.mm | 683 +++++++++----- .../mac/service/ConsoleWindow.xib | 110 +++ .../mac/service/ConsoleWindowController.h | 23 + .../mac/service/ConsoleWindowController.m | 100 ++ .../proj.ios_mac/mac/service/DeviceEx-mac.mm | 70 ++ .../mac/service/PlayerEditBoxServiceMac.h | 61 ++ .../mac/service/PlayerEditBoxServiceMac.mm | 226 +++++ .../mac/service/PlayerFileDialogServiceMac.h | 50 + .../mac/service/PlayerFileDialogServiceMac.mm | 174 ++++ .../proj.ios_mac/mac/service/PlayerMac.h | 52 ++ .../proj.ios_mac/mac/service/PlayerMac.mm | 135 +++ .../mac/service/PlayerMenuServiceMac.h | 78 ++ .../mac/service/PlayerMenuServiceMac.mm | 370 ++++++++ .../mac/service/PlayerMessageBoxServiceMac.h | 29 + .../mac/service/PlayerMessageBoxServiceMac.mm | 58 ++ .../mac/service/PlayerTaskServiceMac.h | 75 ++ .../mac/service/PlayerTaskServiceMac.mm | 241 +++++ .../mac/service/openudid/OpenUDIDMac.h | 65 ++ .../mac/service/openudid/OpenUDIDMac.m | 383 ++++++++ .../mac/zh-Hans.lproj/MainMenu.xib | 197 ++++ .../runtime-src/proj.win32/HelloLua.vcxproj | 64 +- .../proj.win32/HelloLua.vcxproj.filters | 150 ++- .../runtime-src/proj.win32/Runtime_win32.cpp | 8 + .../proj.win32/SimulatorWindow.cpp | 369 -------- .../runtime-src/proj.win32/SimulatorWindow.h | 33 - .../frameworks/runtime-src/proj.win32/game.rc | 51 +- .../runtime-src/proj.win32/main.cpp | 75 +- .../proj.win32/service/DeviceEx-win32.cpp | 137 +++ .../service/PlayerEditBoxServiceWin.cpp | 98 ++ .../service/PlayerEditBoxServiceWin.h | 36 + .../service/PlayerFileDialogServiceWin.cpp | 265 ++++++ .../service/PlayerFileDialogServiceWin.h | 38 + .../service/PlayerMenuServiceWin.cpp | 351 +++++++ .../proj.win32/service/PlayerMenuServiceWin.h | 70 ++ .../service/PlayerMessageBoxServiceWin.cpp | 67 ++ .../service/PlayerMessageBoxServiceWin.h | 28 + .../service/PlayerTaskServiceWin.cpp | 272 ++++++ .../proj.win32/service/PlayerTaskServiceWin.h | 65 ++ .../proj.win32/service/PlayerWin.cpp | 863 ++++++++++++++++++ .../proj.win32/service/PlayerWin.h | 82 ++ .../runtime-src/proj.win32/service/resource.h | 38 + .../runtime-src/proj.win32/service/stdafx.cpp | 8 + .../runtime-src/proj.win32/service/stdafx.h | 21 + .../proj.win32/service/targetver.h | 8 + 87 files changed, 9282 insertions(+), 833 deletions(-) create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/ProjectConfig.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/ProjectConfig.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/SimulatorConfig.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/SimulatorConfig.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/cocos2dx_extra.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/lang create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequest.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequest.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequestDelegate.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppEvent.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppEvent.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppLang.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppLang.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/DeviceEx.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerEditBoxServiceProtocol.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerFileDialogServiceProtocol.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMacros.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMenuServiceProtocol.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMenuServiceProtocol.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMessageBoxServiceProtocol.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerProtocol.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerProtocol.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerServiceProtocol.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerServiceProtocol.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerSettings.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerSettings.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerTaskServiceProtocol.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerTaskServiceProtocol.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerUtils.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerUtils.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/Base.lproj/MainMenu.xib create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindow.xib create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindowController.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindowController.m create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/DeviceEx-mac.mm create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerEditBoxServiceMac.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerEditBoxServiceMac.mm create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerFileDialogServiceMac.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerFileDialogServiceMac.mm create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMac.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMac.mm create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMenuServiceMac.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMenuServiceMac.mm create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMessageBoxServiceMac.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMessageBoxServiceMac.mm create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerTaskServiceMac.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerTaskServiceMac.mm create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/openudid/OpenUDIDMac.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/openudid/OpenUDIDMac.m create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/zh-Hans.lproj/MainMenu.xib delete mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/SimulatorWindow.cpp delete mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/SimulatorWindow.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/DeviceEx-win32.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerEditBoxServiceWin.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerEditBoxServiceWin.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerFileDialogServiceWin.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerFileDialogServiceWin.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMenuServiceWin.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMenuServiceWin.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMessageBoxServiceWin.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMessageBoxServiceWin.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerTaskServiceWin.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerTaskServiceWin.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerWin.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerWin.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/resource.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/stdafx.cpp create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/stdafx.h create mode 100644 templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/targetver.h diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/AppDelegate.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/AppDelegate.cpp index 99d1860936..c558d0a0bf 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/Classes/AppDelegate.cpp +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/AppDelegate.cpp @@ -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 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); + } +} diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/AppDelegate.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/AppDelegate.h index a2699dc754..eed4bacbb1 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/Classes/AppDelegate.h +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/AppDelegate.h @@ -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 _previewFunc; + std::string _launchEvent; }; #endif // __APP_DELEGATE_H__ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/ConfigParser.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ConfigParser.cpp index 1bb12682dc..87b3fbe0f0 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/Classes/ConfigParser.cpp +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ConfigParser.cpp @@ -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 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; +} diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/ConfigParser.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ConfigParser.h index 6bc2515339..8e7e2d2d91 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/Classes/ConfigParser.h +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ConfigParser.h @@ -5,22 +5,12 @@ #include #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 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; }; diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/ProjectConfig.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/ProjectConfig.cpp new file mode 100644 index 0000000000..26aabcb744 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/ProjectConfig.cpp @@ -0,0 +1,791 @@ + +#include + +#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 &split(const std::string &s, char delim, std::vector &elems) { + std::stringstream ss(s); + std::string item; + while (std::getline(ss, item, delim)) { + elems.push_back(item); + } + return elems; +} + + +static std::vector split(const std::string &s, char delim) { + std::vector 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 ProjectConfig::getPackagePathArray() const +{ + vector 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 &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 pathes = split((*it), ';'); + setSearchPath(pathes); + } + + ++it; + } +} + +string ProjectConfig::makeCommandLine(unsigned int mask /* = kProjectConfigAll */) const +{ + stringstream buff; + + vector 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 ProjectConfig::makeCommandLineVector(unsigned int mask /* = kProjectConfigAll */) const +{ + vector 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 &args) +{ + _searchPath = args; +} + +const vector &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 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 +} diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/ProjectConfig.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/ProjectConfig.h new file mode 100644 index 0000000000..22958bf5c6 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/ProjectConfig.h @@ -0,0 +1,148 @@ + +#ifndef __PROJECT_CONFIG_H_ +#define __PROJECT_CONFIG_H_ + +#include +#include + +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 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 &args); + string makeCommandLine(unsigned int mask = kProjectConfigAll) const; + vector 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 &args); + const vector &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 _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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/SimulatorConfig.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/SimulatorConfig.cpp new file mode 100644 index 0000000000..092a7a8fdf --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/SimulatorConfig.cpp @@ -0,0 +1,77 @@ + +#include "SimulatorConfig.h" +#include + +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); + } +} diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/SimulatorConfig.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/SimulatorConfig.h new file mode 100644 index 0000000000..e8306272f4 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/ProjectConfig/SimulatorConfig.h @@ -0,0 +1,57 @@ + +#ifndef __SIMULATOR_CONFIG_H_ +#define __SIMULATOR_CONFIG_H_ + +#include +#include + +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 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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/cocos2dx_extra.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/cocos2dx_extra.h new file mode 100644 index 0000000000..cf7f3c8354 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/cocos2dx_extra.h @@ -0,0 +1,15 @@ + +#ifndef __COCOS2D_X_EXTRA_H_ +#define __COCOS2D_X_EXTRA_H_ + +#include "cocos2d.h" +#include + +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_ */ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/lang b/templates/lua-template-runtime/frameworks/runtime-src/Classes/lang new file mode 100644 index 0000000000..fa00857116 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/lang @@ -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": "缩放" + } +} \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequest.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequest.cpp new file mode 100644 index 0000000000..d6cbd25b47 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequest.cpp @@ -0,0 +1,554 @@ +#include "network/CCHTTPRequest.h" +#include +#include +#include + +#if CC_LUA_ENGINE_ENABLED > 0 +extern "C" { +#include "lua.h" +} +#include "CCLuaEngine.h" +#endif +#include + + +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(_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(_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(_responseBuffer) + _responseDataLength, buffer, bytes); + _responseDataLength += bytes; + static_cast(_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(userdata)->onRequest(); + return 0; +} +#else // _WINDOWS_ +void *HTTPRequest::requestCURL(void *userdata) +{ + static_cast(userdata)->onRequest(); + return NULL; +} +#endif // _WINDOWS_ + +size_t HTTPRequest::writeDataCURL(void *buffer, size_t size, size_t nmemb, void *userdata) +{ + return static_cast(userdata)->onWriteData(buffer, size *nmemb); +} + +size_t HTTPRequest::writeHeaderCURL(void *buffer, size_t size, size_t nmemb, void *userdata) +{ + return static_cast(userdata)->onWriteHeader(buffer, size *nmemb); +} + +int HTTPRequest::progressCURL(void *userdata, double dltotal, double dlnow, double ultotal, double ulnow) +{ + return static_cast(userdata)->onProgress(dltotal, dlnow, ultotal, ulnow); +} + +NS_CC_EXTRA_END diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequest.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequest.h new file mode 100644 index 0000000000..5f37e9f41e --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequest.h @@ -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 +#else +#include +#endif + +#include +#include +#include +#include +#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 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 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_ */ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequestDelegate.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequestDelegate.h new file mode 100644 index 0000000000..aa23425a9b --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/network/CCHTTPRequestDelegate.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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/ConsoleCommand.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/ConsoleCommand.cpp index 3c7733b574..ba1b16a32a 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/ConsoleCommand.cpp +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/ConsoleCommand.cpp @@ -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); diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/FileServer.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/FileServer.cpp index ba4217e3db..cd490ddb24 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/FileServer.cpp +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/FileServer.cpp @@ -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 */ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/Runtime.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/Runtime.cpp index c2088d222d..325196e949 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/Runtime.cpp +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/Runtime.cpp @@ -35,19 +35,15 @@ THE SOFTWARE. #include static std::string g_projectPath; +static std::function 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 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 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); +} \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/Runtime.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/Runtime.h index 7cede048ba..ffe85d9b31 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/Runtime.h +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/runtime/Runtime.h @@ -26,6 +26,7 @@ THE SOFTWARE. #define _RUNTIME__H_ #include +#include 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 func); + #endif // _RUNTIME__H_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppEvent.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppEvent.cpp new file mode 100644 index 0000000000..85dfe64aac --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppEvent.cpp @@ -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; +} \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppEvent.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppEvent.h new file mode 100644 index 0000000000..0810ac5769 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppEvent.h @@ -0,0 +1,47 @@ +// +// AppEvent.h +// Simulator +// +// + +#ifndef __Simulator__AppEvent__ +#define __Simulator__AppEvent__ + +#include +#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__) */ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppLang.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppLang.cpp new file mode 100644 index 0000000000..11d9319522 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppLang.cpp @@ -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; +} diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppLang.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppLang.h new file mode 100644 index 0000000000..8fc1c4f801 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/AppLang.h @@ -0,0 +1,33 @@ +// +// AppLang.h +// Simulator +// + +#ifndef __Simulator__AppLang__ +#define __Simulator__AppLang__ + +#include "cocos2d.h" +#include + +#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__) */ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/DeviceEx.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/DeviceEx.h new file mode 100644 index 0000000000..7a168ef93f --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/DeviceEx.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#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 \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerEditBoxServiceProtocol.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerEditBoxServiceProtocol.h new file mode 100644 index 0000000000..f751cd4d76 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerEditBoxServiceProtocol.h @@ -0,0 +1,37 @@ + +#ifndef __PLAYER_EDITBOX_SERVICE_PROTOCOL_H_ +#define __PLAYER_EDITBOX_SERVICE_PROTOCOL_H_ + +#include + +#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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerFileDialogServiceProtocol.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerFileDialogServiceProtocol.h new file mode 100644 index 0000000000..756d9323a9 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerFileDialogServiceProtocol.h @@ -0,0 +1,33 @@ + +#ifndef __PLAYER_FILE_DIALOG_SERVICE_PROTOCOL_H_ +#define __PLAYER_FILE_DIALOG_SERVICE_PROTOCOL_H_ + +#include +#include + +#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 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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMacros.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMacros.h new file mode 100644 index 0000000000..32bedbe7b4 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMacros.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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMenuServiceProtocol.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMenuServiceProtocol.cpp new file mode 100644 index 0000000000..30de089f04 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMenuServiceProtocol.cpp @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMenuServiceProtocol.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMenuServiceProtocol.h new file mode 100644 index 0000000000..dae521824b --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMenuServiceProtocol.h @@ -0,0 +1,66 @@ + +#ifndef __PLAYER_MENU_SERVICE_PROTOCOL_H +#define __PLAYER_MENU_SERVICE_PROTOCOL_H + +#include + +#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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMessageBoxServiceProtocol.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMessageBoxServiceProtocol.h new file mode 100644 index 0000000000..eb6e3fc0c8 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerMessageBoxServiceProtocol.h @@ -0,0 +1,35 @@ + +#ifndef __PLAYER_MESSAGEBOX_SERVICE_PROTOCOL_H +#define __PLAYER_MESSAGEBOX_SERVICE_PROTOCOL_H + +#include + +#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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerProtocol.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerProtocol.cpp new file mode 100644 index 0000000000..b428f6e658 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerProtocol.cpp @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerProtocol.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerProtocol.h new file mode 100644 index 0000000000..df7f80d40a --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerProtocol.h @@ -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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerServiceProtocol.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerServiceProtocol.cpp new file mode 100644 index 0000000000..b6623b928f --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerServiceProtocol.cpp @@ -0,0 +1,6 @@ + +#include "PlayerServiceProtocol.h" + +PLAYER_NS_BEGIN + +PLAYER_NS_END diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerServiceProtocol.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerServiceProtocol.h new file mode 100644 index 0000000000..cdaeb836c4 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerServiceProtocol.h @@ -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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerSettings.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerSettings.cpp new file mode 100644 index 0000000000..1acc234448 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerSettings.cpp @@ -0,0 +1,2 @@ + +#include "PlayerSettings.h" diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerSettings.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerSettings.h new file mode 100644 index 0000000000..b98e628508 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerTaskServiceProtocol.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerTaskServiceProtocol.cpp new file mode 100644 index 0000000000..394429695c --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerTaskServiceProtocol.cpp @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerTaskServiceProtocol.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerTaskServiceProtocol.h new file mode 100644 index 0000000000..02274acf60 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerTaskServiceProtocol.h @@ -0,0 +1,63 @@ + +#ifndef __PLAYER_TASK_SERVICE_PROTOCOL_H +#define __PLAYER_TASK_SERVICE_PROTOCOL_H + +#include + +#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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerUtils.cpp b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerUtils.cpp new file mode 100644 index 0000000000..0dee5a5648 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerUtils.cpp @@ -0,0 +1,2 @@ + +#include "PlayerUtils.h" diff --git a/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerUtils.h b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerUtils.h new file mode 100644 index 0000000000..b06fb94b22 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/Classes/service/PlayerUtils.h @@ -0,0 +1,36 @@ + +#ifndef __PLAYER_UTILS_H_ +#define __PLAYER_UTILS_H_ + +#include "PlayerMacros.h" + +#include +#include + +using namespace std; + +PLAYER_NS_BEGIN + +template +vector splitString(T str, T pattern) +{ + vector 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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.android/jni/Android.mk b/templates/lua-template-runtime/frameworks/runtime-src/proj.android/jni/Android.mk index c575689908..ef9e414e37 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.android/jni/Android.mk +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.android/jni/Android.mk @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/HelloLua.xcodeproj/project.pbxproj b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/HelloLua.xcodeproj/project.pbxproj index 3bbfe950e6..ca5e2fec39 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/HelloLua.xcodeproj/project.pbxproj +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/HelloLua.xcodeproj/project.pbxproj @@ -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 = ""; }; 521A8E6F19F0C3D200D177D7 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = ""; }; + 9FFC06EA1A4A733B00AED399 /* ConsoleWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConsoleWindow.xib; sourceTree = ""; }; + 9FFC06EB1A4A733B00AED399 /* ConsoleWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleWindowController.h; sourceTree = ""; }; + 9FFC06EC1A4A733B00AED399 /* ConsoleWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConsoleWindowController.m; sourceTree = ""; }; + 9FFC06ED1A4A733B00AED399 /* PlayerEditBoxServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerEditBoxServiceMac.h; sourceTree = ""; }; + 9FFC06EE1A4A733B00AED399 /* PlayerEditBoxServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerEditBoxServiceMac.mm; sourceTree = ""; }; + 9FFC06EF1A4A733B00AED399 /* PlayerFileDialogServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerFileDialogServiceMac.h; sourceTree = ""; }; + 9FFC06F01A4A733B00AED399 /* PlayerFileDialogServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerFileDialogServiceMac.mm; sourceTree = ""; }; + 9FFC06F11A4A733B00AED399 /* PlayerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMac.h; sourceTree = ""; }; + 9FFC06F21A4A733B00AED399 /* PlayerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerMac.mm; sourceTree = ""; }; + 9FFC06F31A4A733B00AED399 /* PlayerMenuServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMenuServiceMac.h; sourceTree = ""; }; + 9FFC06F41A4A733B00AED399 /* PlayerMenuServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerMenuServiceMac.mm; sourceTree = ""; }; + 9FFC06F51A4A733B00AED399 /* PlayerMessageBoxServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMessageBoxServiceMac.h; sourceTree = ""; }; + 9FFC06F61A4A733B00AED399 /* PlayerMessageBoxServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerMessageBoxServiceMac.mm; sourceTree = ""; }; + 9FFC06F71A4A733B00AED399 /* PlayerTaskServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerTaskServiceMac.h; sourceTree = ""; }; + 9FFC06F81A4A733B00AED399 /* PlayerTaskServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlayerTaskServiceMac.mm; sourceTree = ""; }; + 9FFC07021A4A737300AED399 /* OpenUDIDMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenUDIDMac.h; sourceTree = ""; }; + 9FFC07031A4A737300AED399 /* OpenUDIDMac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OpenUDIDMac.m; sourceTree = ""; }; + 9FFC07051A4A739200AED399 /* cocos2dx_extra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cocos2dx_extra.h; path = ../Classes/cocos2dx_extra.h; sourceTree = ""; }; + 9FFC07061A4A739200AED399 /* lang */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = lang; path = ../Classes/lang; sourceTree = ""; }; + 9FFC07081A4A739200AED399 /* CCHTTPRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCHTTPRequest.cpp; sourceTree = ""; }; + 9FFC07091A4A739200AED399 /* CCHTTPRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCHTTPRequest.h; sourceTree = ""; }; + 9FFC070A1A4A739200AED399 /* CCHTTPRequestDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCHTTPRequestDelegate.h; sourceTree = ""; }; + 9FFC070C1A4A739200AED399 /* ProjectConfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectConfig.cpp; sourceTree = ""; }; + 9FFC070D1A4A739200AED399 /* ProjectConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectConfig.h; sourceTree = ""; }; + 9FFC070E1A4A739200AED399 /* SimulatorConfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimulatorConfig.cpp; sourceTree = ""; }; + 9FFC070F1A4A739200AED399 /* SimulatorConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimulatorConfig.h; sourceTree = ""; }; + 9FFC07111A4A739200AED399 /* AppEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppEvent.cpp; sourceTree = ""; }; + 9FFC07121A4A739200AED399 /* AppEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppEvent.h; sourceTree = ""; }; + 9FFC07131A4A739200AED399 /* AppLang.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppLang.cpp; sourceTree = ""; }; + 9FFC07141A4A739200AED399 /* AppLang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppLang.h; sourceTree = ""; }; + 9FFC07151A4A739200AED399 /* DeviceEx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceEx.h; sourceTree = ""; }; + 9FFC07161A4A739200AED399 /* PlayerEditBoxServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerEditBoxServiceProtocol.h; sourceTree = ""; }; + 9FFC07171A4A739200AED399 /* PlayerFileDialogServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerFileDialogServiceProtocol.h; sourceTree = ""; }; + 9FFC07181A4A739200AED399 /* PlayerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMacros.h; sourceTree = ""; }; + 9FFC07191A4A739200AED399 /* PlayerMenuServiceProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerMenuServiceProtocol.cpp; sourceTree = ""; }; + 9FFC071A1A4A739200AED399 /* PlayerMenuServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMenuServiceProtocol.h; sourceTree = ""; }; + 9FFC071B1A4A739200AED399 /* PlayerMessageBoxServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerMessageBoxServiceProtocol.h; sourceTree = ""; }; + 9FFC071C1A4A739200AED399 /* PlayerProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerProtocol.cpp; sourceTree = ""; }; + 9FFC071D1A4A739200AED399 /* PlayerProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerProtocol.h; sourceTree = ""; }; + 9FFC071E1A4A739200AED399 /* PlayerServiceProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerServiceProtocol.cpp; sourceTree = ""; }; + 9FFC071F1A4A739200AED399 /* PlayerServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerServiceProtocol.h; sourceTree = ""; }; + 9FFC07201A4A739200AED399 /* PlayerSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerSettings.cpp; sourceTree = ""; }; + 9FFC07211A4A739200AED399 /* PlayerSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerSettings.h; sourceTree = ""; }; + 9FFC07221A4A739200AED399 /* PlayerTaskServiceProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerTaskServiceProtocol.cpp; sourceTree = ""; }; + 9FFC07231A4A739200AED399 /* PlayerTaskServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerTaskServiceProtocol.h; sourceTree = ""; }; + 9FFC07241A4A739200AED399 /* PlayerUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayerUtils.cpp; sourceTree = ""; }; + 9FFC07251A4A739200AED399 /* PlayerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerUtils.h; sourceTree = ""; }; + 9FFC07321A4A73F700AED399 /* DeviceEx-mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DeviceEx-mac.mm"; sourceTree = ""; }; + 9FFC07351A4A764100AED399 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 9FFC07371A4A765100AED399 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.xib"; sourceTree = ""; }; + 9FFC07381A4A902500AED399 /* CodeIDESupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeIDESupport.h; path = ../Classes/CodeIDESupport.h; sourceTree = ""; }; AB6CB6EC1A1F275E009C2562 /* ConnectWaitLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConnectWaitLayer.cpp; sourceTree = ""; }; AB6CB6ED1A1F275E009C2562 /* ConnectWaitLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectWaitLayer.h; sourceTree = ""; }; AB6CB6EE1A1F275E009C2562 /* ConsoleCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleCommand.cpp; sourceTree = ""; }; @@ -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 = ""; }; F293BB7F15EB831F00256477 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../Classes/AppDelegate.h; sourceTree = ""; }; - F405C6CA19ED14AA005AD31C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; /* 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 = ""; }; + 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 = ""; + }; + 9FFC07011A4A737300AED399 /* openudid */ = { + isa = PBXGroup; + children = ( + 9FFC07021A4A737300AED399 /* OpenUDIDMac.h */, + 9FFC07031A4A737300AED399 /* OpenUDIDMac.m */, + ); + path = openudid; + sourceTree = ""; + }; + 9FFC07071A4A739200AED399 /* network */ = { + isa = PBXGroup; + children = ( + 9FFC07081A4A739200AED399 /* CCHTTPRequest.cpp */, + 9FFC07091A4A739200AED399 /* CCHTTPRequest.h */, + 9FFC070A1A4A739200AED399 /* CCHTTPRequestDelegate.h */, + ); + name = network; + path = ../Classes/network; + sourceTree = ""; + }; + 9FFC070B1A4A739200AED399 /* ProjectConfig */ = { + isa = PBXGroup; + children = ( + 9FFC070C1A4A739200AED399 /* ProjectConfig.cpp */, + 9FFC070D1A4A739200AED399 /* ProjectConfig.h */, + 9FFC070E1A4A739200AED399 /* SimulatorConfig.cpp */, + 9FFC070F1A4A739200AED399 /* SimulatorConfig.h */, + ); + name = ProjectConfig; + path = ../Classes/ProjectConfig; + sourceTree = ""; + }; + 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 = ""; + }; 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 = ""; @@ -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; diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/Runtime_ios-mac.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/Runtime_ios-mac.mm index ffa8f82acc..430ac534e0 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/Runtime_ios-mac.mm +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/Runtime_ios-mac.mm @@ -5,6 +5,9 @@ #include #include + +#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; diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/Base.lproj/MainMenu.xib b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/Base.lproj/MainMenu.xib new file mode 100644 index 0000000000..95349511fa --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/Base.lproj/MainMenu.xib @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.h index d7815e3ef7..ca4b60ed34 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.h +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.h @@ -24,29 +24,35 @@ #include +#import + +#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 +@interface AppController : NSObject { - 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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.mm index 7d263e4868..6d0ce2d5cb 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.mm +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.mm @@ -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); + + _debugLogFile = 0; - 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]; + [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 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 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 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 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(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(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(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(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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindow.xib b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindow.xib new file mode 100644 index 0000000000..1cc9932310 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindow.xib @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindowController.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindowController.h new file mode 100644 index 0000000000..7b1c06d215 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindowController.h @@ -0,0 +1,23 @@ + +#import + +@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 + + + diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindowController.m b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindowController.m new file mode 100644 index 0000000000..aa56938433 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/ConsoleWindowController.m @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/DeviceEx-mac.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/DeviceEx-mac.mm new file mode 100644 index 0000000000..afae0e88c7 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/DeviceEx-mac.mm @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerEditBoxServiceMac.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerEditBoxServiceMac.h new file mode 100644 index 0000000000..94f52bcaba --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerEditBoxServiceMac.h @@ -0,0 +1,61 @@ +// +// EditBoxServiceMac.h +// player +// + +#ifndef __player__EditBoxServiceMac__ +#define __player__EditBoxServiceMac__ + +#include "PlayerEditBoxServiceProtocol.h" + + +@interface EditBoxServiceImplMac : NSObject +{ + 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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerEditBoxServiceMac.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerEditBoxServiceMac.mm new file mode 100644 index 0000000000..dc2b960130 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerEditBoxServiceMac.mm @@ -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(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; \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerFileDialogServiceMac.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerFileDialogServiceMac.h new file mode 100644 index 0000000000..c71c0c6b1e --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerFileDialogServiceMac.h @@ -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 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 \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerFileDialogServiceMac.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerFileDialogServiceMac.mm new file mode 100644 index 0000000000..413452bf9a --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerFileDialogServiceMac.mm @@ -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 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 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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMac.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMac.h new file mode 100644 index 0000000000..971ada3630 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMac.h @@ -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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMac.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMac.mm new file mode 100644 index 0000000000..7bebdfeb04 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMac.mm @@ -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(Director::getInstance()->getOpenGLView())->getCocoaWindow(); + return window.frame.origin.x; +} + +int PlayerMac::getPositionY() +{ + NSWindow *window = dynamic_cast(Director::getInstance()->getOpenGLView())->getCocoaWindow(); + return window.frame.origin.y; +} + +PLAYER_NS_END diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMenuServiceMac.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMenuServiceMac.h new file mode 100644 index 0000000000..228b4caf92 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMenuServiceMac.h @@ -0,0 +1,78 @@ + +#ifndef __PLAYER_MENU_SERVICE_MAC_H_ +#define __PLAYER_MENU_SERVICE_MAC_H_ + +#include + +#include "cocos2d.h" +#include "PlayerMacros.h" +#include "PlayerMenuServiceProtocol.h" + +// +// Menu item Helper +// + +PLAYER_NS_BEGIN +class PlayerMenuItemMac; +PLAYER_NS_END + +@interface NNMenuItem : NSMenuItem +@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 _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 _items; +}; + +PLAYER_NS_END + +#endif // __PLAYER_MENU_SERVICE_MAC_H_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMenuServiceMac.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMenuServiceMac.mm new file mode 100644 index 0000000000..882198a28a --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMenuServiceMac.mm @@ -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 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 \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMessageBoxServiceMac.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMessageBoxServiceMac.h new file mode 100644 index 0000000000..0aec41fae5 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMessageBoxServiceMac.h @@ -0,0 +1,29 @@ + +#ifndef __PLAYER_MessageBoxServiceMac_h +#define __PLAYER_MessageBoxServiceMac_h + +#include + +#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 getTitles(int buttons); +}; + +PLAYER_NS_END + +#endif // __PLAYER_MessageBoxServiceMac_h diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMessageBoxServiceMac.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMessageBoxServiceMac.mm new file mode 100644 index 0000000000..fe3f77b5ad --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerMessageBoxServiceMac.mm @@ -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::getTitles(int buttons) +{ + std::vector 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 \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerTaskServiceMac.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerTaskServiceMac.h new file mode 100644 index 0000000000..9adbeeb993 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerTaskServiceMac.h @@ -0,0 +1,75 @@ + +#ifndef __PLAYER_TASK_SERVICE_MAC_H_ +#define __PLAYER_TASK_SERVICE_MAC_H_ + +#include + +#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 _tasks; +}; + +PLAYER_NS_END + + +#endif // __PLAYER_TASK_SERVICE_MAC_H_ \ No newline at end of file diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerTaskServiceMac.mm b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerTaskServiceMac.mm new file mode 100644 index 0000000000..6d011ffd68 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/PlayerTaskServiceMac.mm @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/openudid/OpenUDIDMac.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/openudid/OpenUDIDMac.h new file mode 100644 index 0000000000..57d5d115bd --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/openudid/OpenUDIDMac.h @@ -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 + +// +// 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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/openudid/OpenUDIDMac.m b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/openudid/OpenUDIDMac.m new file mode 100644 index 0000000000..9e9026cabb --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/service/openudid/OpenUDIDMac.m @@ -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 // Need to import for CC_MD5 access +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +#import +#import +#else +#import +#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; n0)? [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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/zh-Hans.lproj/MainMenu.xib b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/zh-Hans.lproj/MainMenu.xib new file mode 100644 index 0000000000..8b6ba8420f --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.ios_mac/mac/zh-Hans.lproj/MainMenu.xib @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/HelloLua.vcxproj b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/HelloLua.vcxproj index 0d9aafbd37..ddb4399b40 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/HelloLua.vcxproj +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/HelloLua.vcxproj @@ -68,7 +68,7 @@ - $(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) + $(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) Level3 @@ -119,7 +119,8 @@ - xcopy /Y /Q "$(OutDir)*.dll" "$(ProjectDir)..\..\..\runtime\win32\" + xcopy /Y /Q "$(OutDir)*.dll" "$(ProjectDir)..\..\..\runtime\win32\" +xcopy /Y /Q "$(ProjectDir)..\Classes\lang" "$(ProjectDir)..\..\..\runtime\win32\" @@ -164,24 +165,25 @@ - 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 - + if not exist "$(LocalDebuggerWorkingDirectory)" mkdir "$(LocalDebuggerWorkingDirectory)" copy files + + xcopy /Y /Q "$(OutDir)*.dll" "$(ProjectDir)..\..\..\runtime\win32\" +xcopy /Y /Q "$(ProjectDir)..\Classes\lang" "$(ProjectDir)..\..\..\runtime\win32\" + + + + + @@ -210,14 +212,37 @@ copy "$(ProjectDir)..\..\..\config.json" "$(LocalDebuggerWorkingDirectory)\confi + + + + + + + + + + + + + - + + + + + + + + + + + @@ -241,10 +266,25 @@ copy "$(ProjectDir)..\..\..\config.json" "$(LocalDebuggerWorkingDirectory)\confi + + + + + + + + - + + + + + + + + diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/HelloLua.vcxproj.filters b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/HelloLua.vcxproj.filters index bae1cfc2f4..e27b524f4d 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/HelloLua.vcxproj.filters +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/HelloLua.vcxproj.filters @@ -16,6 +16,18 @@ {28edb895-7c19-408b-abd6-130196087d96} + + {b0ffeea4-e5fa-483a-8be4-c26a9ed47c60} + + + {e2010b29-c067-4846-8f28-667d95056987} + + + {6a6237c1-312d-4c66-82b3-b0de869920c8} + + + {9d6fbab4-6525-4c43-9438-9d3923429d52} + @@ -24,9 +36,6 @@ win32 - - win32 - Classes @@ -118,6 +127,81 @@ Classes\runtime + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\network + + + Classes\network + + + Classes\ProjectConfig + + + Classes\ProjectConfig + + + win32\service + + + win32\service + + + win32\service + + + win32\service + + + win32\service + + + win32\service + + + win32\service + + + win32\service + @@ -126,9 +210,6 @@ win32 - - win32 - win32 @@ -207,6 +288,63 @@ Classes\runtime + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\service + + + Classes\network + + + Classes\ProjectConfig + + + Classes\ProjectConfig + + + win32\service + + + win32\service + + + win32\service + + + win32\service + + + win32\service + + + win32\service + + + win32\service + + + win32\service + diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/Runtime_win32.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/Runtime_win32.cpp index cb2671d0c4..aa06b86d29 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/Runtime_win32.cpp +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/Runtime_win32.cpp @@ -6,6 +6,7 @@ #include #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) diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/SimulatorWindow.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/SimulatorWindow.cpp deleted file mode 100644 index 8b6ffb025e..0000000000 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/SimulatorWindow.cpp +++ /dev/null @@ -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 -#include -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(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()); - } - -} diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/SimulatorWindow.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/SimulatorWindow.h deleted file mode 100644 index abb12ab69d..0000000000 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/SimulatorWindow.h +++ /dev/null @@ -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_ */ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/game.rc b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/game.rc index 46a66d6cf7..6df3e868ac 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/game.rc +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/game.rc @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/main.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/main.cpp index 8f4987defa..9ddaf6e212 100644 --- a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/main.cpp +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/main.cpp @@ -1,73 +1,14 @@ #include "main.h" -#include "AppDelegate.h" -#include "cocos2d.h" +#include "service/PlayerWin.h" #include -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(); } diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/DeviceEx-win32.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/DeviceEx-win32.cpp new file mode 100644 index 0000000000..0434edab72 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/DeviceEx-win32.cpp @@ -0,0 +1,137 @@ +#include "DeviceEx.h" + +// for mac address +#include +#include +#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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerEditBoxServiceWin.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerEditBoxServiceWin.cpp new file mode 100644 index 0000000000..fd0d0270d4 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerEditBoxServiceWin.cpp @@ -0,0 +1,98 @@ + +#include + +#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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerEditBoxServiceWin.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerEditBoxServiceWin.h new file mode 100644 index 0000000000..a481720e6f --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerEditBoxServiceWin.h @@ -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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerFileDialogServiceWin.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerFileDialogServiceWin.cpp new file mode 100644 index 0000000000..53a20d5e5c --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerFileDialogServiceWin.cpp @@ -0,0 +1,265 @@ + +#include + +#include "stdafx.h" +#include +#include +#include + +#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 result = openMultipleInternal(title, directory, extensions, false); + if (result.size()) + { + return result.at(0); + } + return std::string(); +} + +std::vector 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 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 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 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 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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerFileDialogServiceWin.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerFileDialogServiceWin.h new file mode 100644 index 0000000000..6804fe6fa5 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerFileDialogServiceWin.h @@ -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 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 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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMenuServiceWin.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMenuServiceWin.cpp new file mode 100644 index 0000000000..66a0cf2af0 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMenuServiceWin.cpp @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMenuServiceWin.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMenuServiceWin.h new file mode 100644 index 0000000000..3d0c13a9ac --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMenuServiceWin.h @@ -0,0 +1,70 @@ + +#ifndef __PLAYER_MENU_SERVICE_WIN_H_ +#define __PLAYER_MENU_SERVICE_WIN_H_ + +#include +#include + +#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 _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 _items; + std::unordered_map _commandId2menuId; + + bool removeItemInternal(const std::string &menuId, bool isUpdateChildrenOrder); + void updateChildrenOrder(PlayerMenuItemWin *parent); +}; + +PLAYER_NS_END + +#endif // __PLAYER_MENU_SERVICE_WIN_H_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMessageBoxServiceWin.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMessageBoxServiceWin.cpp new file mode 100644 index 0000000000..bbcdca47eb --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMessageBoxServiceWin.cpp @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMessageBoxServiceWin.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMessageBoxServiceWin.h new file mode 100644 index 0000000000..ecff6d3ffc --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerMessageBoxServiceWin.h @@ -0,0 +1,28 @@ + +#ifndef __PLAYER_MESSAGEBOX_SERVICE_WIN_H_ +#define __PLAYER_MESSAGEBOX_SERVICE_WIN_H_ + +#include + +#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_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerTaskServiceWin.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerTaskServiceWin.cpp new file mode 100644 index 0000000000..4e65e03fa4 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerTaskServiceWin.cpp @@ -0,0 +1,272 @@ + +#include + +#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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerTaskServiceWin.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerTaskServiceWin.h new file mode 100644 index 0000000000..578bd81a0a --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerTaskServiceWin.h @@ -0,0 +1,65 @@ + +#ifndef __PLAYER_TASK_SERVICE_WIN_H_ +#define __PLAYER_TASK_SERVICE_WIN_H_ + +#include + +#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 _tasks; +}; + +PLAYER_NS_END + +#endif // __PLAYER_TASK_SERVICE_WIN_H_ diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerWin.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerWin.cpp new file mode 100644 index 0000000000..aa62c3033c --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerWin.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 (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 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 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(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(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(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(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 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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerWin.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerWin.h new file mode 100644 index 0000000000..8b815ab5f0 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/PlayerWin.h @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/resource.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/resource.h new file mode 100644 index 0000000000..7515c91c41 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/resource.h @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/stdafx.cpp b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/stdafx.cpp new file mode 100644 index 0000000000..b8b9773e01 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/stdafx.cpp @@ -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 diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/stdafx.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/stdafx.h new file mode 100644 index 0000000000..bb80440ee2 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/stdafx.h @@ -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 + +// C RunTime Header Files +#include +#include +#include +#include + + +// TODO: reference additional headers your program requires here diff --git a/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/targetver.h b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/targetver.h new file mode 100644 index 0000000000..87c0086de7 --- /dev/null +++ b/templates/lua-template-runtime/frameworks/runtime-src/proj.win32/service/targetver.h @@ -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