diff --git a/frameworks/cocos2d-html5 b/frameworks/cocos2d-html5
index 9aed43ac69..fa68c45229 160000
--- a/frameworks/cocos2d-html5
+++ b/frameworks/cocos2d-html5
@@ -1 +1 @@
-Subproject commit 9aed43ac69ae1f3b5f0a1257b845d5481263391d
+Subproject commit fa68c45229f8929fab5b73a7679896804880cb58
diff --git a/frameworks/js-bindings/bindings/manual/ScriptingCore.cpp b/frameworks/js-bindings/bindings/manual/ScriptingCore.cpp
index a10a402f29..67c2ba1a6f 100644
--- a/frameworks/js-bindings/bindings/manual/ScriptingCore.cpp
+++ b/frameworks/js-bindings/bindings/manual/ScriptingCore.cpp
@@ -354,6 +354,24 @@ bool JSBCore_os(JSContext *cx, uint32_t argc, jsval *vp)
return true;
};
+bool JSB_cleanScript(JSContext *cx, uint32_t argc, jsval *vp)
+{
+ if (argc != 1)
+ {
+ JS_ReportError(cx, "Invalid number of arguments in JSB_cleanScript");
+ return false;
+ }
+ jsval *argv = JS_ARGV(cx, vp);
+ JSString *jsPath = JSVAL_TO_STRING(argv[0]);
+ JSB_PRECONDITION2(jsPath, cx, false, "Error js file in clean script");
+ JSStringWrapper wrapper(jsPath);
+ ScriptingCore::getInstance()->cleanScript(wrapper.get());
+
+ JS_SET_RVAL(cx, vp, JSVAL_VOID);
+
+ return true;
+};
+
bool JSB_core_restartVM(JSContext *cx, uint32_t argc, jsval *vp)
{
JSB_PRECONDITION2(argc==0, cx, false, "Invalid number of arguments in executeScript");
@@ -394,11 +412,12 @@ void registerDefaultClasses(JSContext* cx, JSObject* global) {
JS_DefineFunction(cx, global, "log", ScriptingCore::log, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, global, "executeScript", ScriptingCore::executeScript, 1, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, global, "forceGC", ScriptingCore::forceGC, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-
+
JS_DefineFunction(cx, global, "__getPlatform", JSBCore_platform, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, global, "__getOS", JSBCore_os, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, global, "__getVersion", JSBCore_version, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, global, "__restartVM", JSB_core_restartVM, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE );
+ JS_DefineFunction(cx, global, "__cleanScript", JSB_cleanScript, 1, JSPROP_READONLY | JSPROP_PERMANENT);
}
static void sc_finalize(JSFreeOp *freeOp, JSObject *obj) {
@@ -422,6 +441,11 @@ ScriptingCore::ScriptingCore()
// set utf8 strings internally (we don't need utf16)
// XXX: Removed in SpiderMonkey 19.0
//JS_SetCStringsAreUTF8();
+ initRegister();
+}
+
+void ScriptingCore::initRegister()
+{
this->addRegisterCallback(registerDefaultClasses);
this->_runLoop = new SimpleRunLoop();
}
@@ -703,9 +727,15 @@ bool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* cx)
}
void ScriptingCore::reset()
+{
+ Director::getInstance()->restart();
+}
+
+void ScriptingCore::restartVM()
{
cleanup();
- start();
+ initRegister();
+ CCApplication::getInstance()->applicationDidFinishLaunching();
}
ScriptingCore::~ScriptingCore()
@@ -741,6 +771,7 @@ void ScriptingCore::cleanup()
_js_global_type_map.clear();
filename_script.clear();
+ registrationList.clear();
}
void ScriptingCore::reportError(JSContext *cx, const char *message, JSErrorReport *report)
@@ -1344,6 +1375,13 @@ int ScriptingCore::sendEvent(ScriptEvent* evt)
if (NULL == evt)
return 0;
+ // special type, can't use this code after JSAutoCompartment
+ if (evt->type == kRestartGame)
+ {
+ restartVM();
+ return 0;
+ }
+
JSAutoCompartment ac(_cx, _global);
switch (evt->type)
diff --git a/frameworks/js-bindings/bindings/manual/ScriptingCore.h b/frameworks/js-bindings/bindings/manual/ScriptingCore.h
index 0ae50e5a18..742a82c62a 100644
--- a/frameworks/js-bindings/bindings/manual/ScriptingCore.h
+++ b/frameworks/js-bindings/bindings/manual/ScriptingCore.h
@@ -247,7 +247,7 @@ class ScriptingCore : public cocos2d::ScriptEngineProtocol
private:
void string_report(jsval val);
-
+ void initRegister();
public:
int handleNodeEvent(void* data);
int handleComponentEvent(void* data);
@@ -257,6 +257,8 @@ class ScriptingCore : public cocos2d::ScriptEngineProtocol
bool handleTouchEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, cocos2d::Touch* touch, cocos2d::Event* event, jsval* jsvalRet = nullptr);
bool handleMouseEvent(void* nativeObj, cocos2d::EventMouse::MouseEventType eventType, cocos2d::Event* event, jsval* jsvalRet = nullptr);
bool handleKeybardEvent(void* nativeObj, cocos2d::EventKeyboard::KeyCode keyCode, bool isPressed, cocos2d::Event* event);
+
+ void restartVM();
};
JSObject* NewGlobalObject(JSContext* cx, bool debug = false);
diff --git a/frameworks/js-bindings/bindings/script/jsb_boot.js b/frameworks/js-bindings/bindings/script/jsb_boot.js
index 00de8416b3..74c28d913e 100644
--- a/frameworks/js-bindings/bindings/script/jsb_boot.js
+++ b/frameworks/js-bindings/bindings/script/jsb_boot.js
@@ -1327,6 +1327,12 @@ cc._initSys = function(config, CONFIG_KEY){
__restartVM();
};
+ // clean a singal js file
+ locSys.cleanScript = function(jsFile) {
+ __cleanScript(jsFile);
+ };
+
+
locSys.dump = function(){
var self = this;
var str = "";
@@ -1506,6 +1512,14 @@ cc.game = {
config[CONFIG_KEY.frameRate] = frameRate;
cc.director.setAnimationInterval(1.0/frameRate);
},
+
+ /**
+ * Restart game.
+ */
+ restart: function () {
+ __restartVM();
+ },
+
/**
* Run game.
*/
@@ -1519,6 +1533,7 @@ cc.game = {
self.onStart();
}
},
+
/**
* Init config.
* @param cb
diff --git a/frameworks/js-bindings/cocos2d-x b/frameworks/js-bindings/cocos2d-x
index 4e6473be00..776aadd4e2 160000
--- a/frameworks/js-bindings/cocos2d-x
+++ b/frameworks/js-bindings/cocos2d-x
@@ -1 +1 @@
-Subproject commit 4e6473be00c6bd44cd9be462a8b4d09de0e4c371
+Subproject commit 776aadd4e29a9beaa14ea53062d7ac8ecf923ea9
diff --git a/samples/js-moonwarriors/project/Classes/AppDelegate.cpp b/samples/js-moonwarriors/project/Classes/AppDelegate.cpp
index 95a9ae66a1..08f7a7557d 100644
--- a/samples/js-moonwarriors/project/Classes/AppDelegate.cpp
+++ b/samples/js-moonwarriors/project/Classes/AppDelegate.cpp
@@ -4,18 +4,8 @@
#include "SimpleAudioEngine.h"
#include "ScriptingCore.h"
#include "jsb_cocos2dx_auto.hpp"
-#include "jsb_cocos2dx_extension_auto.hpp"
-#include "jsb_cocos2dx_builder_auto.hpp"
-#include "extension/jsb_cocos2dx_extension_manual.h"
#include "cocos2d_specifics.hpp"
-#include "cocosbuilder/js_bindings_ccbreader.h"
#include "localstorage/js_bindings_system_registration.h"
-#include "chipmunk/js_bindings_chipmunk_registration.h"
-#include "jsb_opengl_registration.h"
-#include "jsb_cocos2dx_ui_auto.hpp"
-#include "ui/jsb_cocos2dx_ui_manual.h"
-#include "cocostudio/jsb_cocos2dx_studio_manual.h"
-#include "jsb_cocos2dx_studio_auto.hpp"
USING_NS_CC;
using namespace CocosDenshion;
@@ -26,7 +16,7 @@ AppDelegate::AppDelegate()
AppDelegate::~AppDelegate()
{
- ScriptEngineManager::destroyInstance();
+ ScriptEngineManager::destroyInstance();
}
void AppDelegate::initGLContextAttrs()
@@ -54,27 +44,13 @@ bool AppDelegate::applicationDidFinishLaunching()
sc->addRegisterCallback(register_cocos2dx_js_core);
sc->addRegisterCallback(register_cocos2dx_js_extensions);
sc->addRegisterCallback(jsb_register_system);
-
- //sc->addRegisterCallback(register_all_cocos2dx_extension);
- //sc->addRegisterCallback(register_all_cocos2dx_extension_manual);
-
- //sc->addRegisterCallback(jsb_register_chipmunk);
- //sc->addRegisterCallback(register_all_cocos2dx_builder);
- //sc->addRegisterCallback(register_CCBuilderReader);
-
- //sc->addRegisterCallback(JSB_register_opengl);
- //sc->addRegisterCallback(register_all_cocos2dx_ui);
- //sc->addRegisterCallback(register_all_cocos2dx_ui_manual);
- //sc->addRegisterCallback(register_all_cocos2dx_studio);
- //sc->addRegisterCallback(register_all_cocos2dx_studio_manual);
-
sc->start();
sc->runScript("script/jsb_boot.js");
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
sc->enableDebugger();
#endif
-
+
auto pEngine = ScriptingCore::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(pEngine);
@@ -90,7 +66,7 @@ void AppDelegate::applicationDidEnterBackground()
director->stopAnimation();
director->getEventDispatcher()->dispatchCustomEvent("game_on_hide");
SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
- SimpleAudioEngine::getInstance()->pauseAllEffects();
+ SimpleAudioEngine::getInstance()->pauseAllEffects();
}
// this function will be called when the app is active again
diff --git a/samples/js-tests/project.json b/samples/js-tests/project.json
index 36988c2b91..1ed27f831b 100644
--- a/samples/js-tests/project.json
+++ b/samples/js-tests/project.json
@@ -70,6 +70,7 @@
"src/EventTest/EventTest.js",
"src/UnitTest/UnitTest.js",
"src/SysTest/SysTest.js",
+ "src/SysTest/ScriptTestTempFile.js",
"src/EffectsTest/EffectsTest.js",
"src/EffectsAdvancedTest/EffectsAdvancedTest.js",
"src/MotionStreakTest/MotionStreakTest.js",
diff --git a/samples/js-tests/res/Manifests/ScriptTest/project.manifest b/samples/js-tests/res/Manifests/ScriptTest/project.manifest
new file mode 100644
index 0000000000..83fb2282ef
--- /dev/null
+++ b/samples/js-tests/res/Manifests/ScriptTest/project.manifest
@@ -0,0 +1,13 @@
+{
+ "packageUrl" : "http://tools.itharbors.com/assets_manager/ScriptTest/",
+ "remoteManifestUrl" : "http://tools.itharbors.com/assets_manager/ScriptTest/project_dev.manifest",
+ "remoteVersionUrl" : "http://tools.itharbors.com/assets_manager/ScriptTest/version_dev.manifest",
+ "version" : "1.0.0",
+ "engineVersion" : "3.0",
+
+ "assets" : {
+ },
+
+ "searchPaths" : [
+ ]
+}
\ No newline at end of file
diff --git a/samples/js-tests/src/SysTest/ScriptTestTempFile.js b/samples/js-tests/src/SysTest/ScriptTestTempFile.js
new file mode 100644
index 0000000000..f9edd31553
--- /dev/null
+++ b/samples/js-tests/src/SysTest/ScriptTestTempFile.js
@@ -0,0 +1,38 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ 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.
+ ****************************************************************************/
+
+var ScriptTestTempLayer = cc.Layer.extend({
+ ctor : function () {
+ this._super();
+
+ var labelTest = new cc.LabelTTF("this is the ScriptTestTempLayer old file", "Verdana", 32, cc.size(winSize.width, 50), cc.TEXT_ALIGNMENT_CENTER);
+ var size = cc.winSize;
+ labelTest.setPosition(size.width / 2, size.height / 4);
+ this.addChild(labelTest);
+
+ }
+
+});
diff --git a/samples/js-tests/src/SysTest/SysTest.js b/samples/js-tests/src/SysTest/SysTest.js
index d772d358cc..532cbd5413 100644
--- a/samples/js-tests/src/SysTest/SysTest.js
+++ b/samples/js-tests/src/SysTest/SysTest.js
@@ -123,16 +123,167 @@ var SysTestScene = TestScene.extend({
}
});
+//------------------------------------------------------------------
+//
+// Script dynamic reload test
+//
+//------------------------------------------------------------------
+var tempJSFileName = "ScriptTestTempFile.js";
+var ScriptTestLayer = SysTestBase.extend({
+ _tempLayer:null,
+ _am : null,
+ startDownload:function () {
+ if (!cc.sys.isNative)
+ {
+ return;
+ }
+ var manifestPath = "Manifests/ScriptTest/project.manifest";
+ var storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : "/") + "JSBTests/AssetsManagerTest/ScriptTest/");
+ cc.log("Storage path for this test : " + storagePath);
+
+ if (this._am)
+ {
+ this._am.release();
+ this._am = null;
+ }
+
+ this._am = new jsb.AssetsManager(manifestPath, storagePath);
+ this._am.retain();
+ if (!this._am.getLocalManifest().isLoaded())
+ {
+ cc.log("Fail to update assets, step skipped.");
+ that.clickMeShowTempLayer();
+ }
+ else {
+ var that = this;
+ var listener = new jsb.EventListenerAssetsManager(this._am, function (event) {
+ var scene;
+ switch (event.getEventCode()) {
+ case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
+ cc.log("No local manifest file found, skip assets update.");
+ that.clickMeShowTempLayer();
+ break;
+ case jsb.EventAssetsManager.UPDATE_PROGRESSION:
+ cc.log(event.getPercent() + "%");
+ break;
+ case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
+ case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
+ cc.log("Fail to download manifest file, update skipped.");
+ that.clickMeShowTempLayer();
+ break;
+ case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
+ case jsb.EventAssetsManager.UPDATE_FINISHED:
+ cc.log("Update finished. " + event.getMessage());
+ require(tempJSFileName);
+ that.clickMeShowTempLayer();
+ break;
+ case jsb.EventAssetsManager.UPDATE_FAILED:
+ cc.log("Update failed. " + event.getMessage());
+ break;
+ case jsb.EventAssetsManager.ERROR_UPDATING:
+ cc.log("Asset update error: " + event.getAssetId() + ", " + event.getMessage());
+ break;
+ case jsb.EventAssetsManager.ERROR_DECOMPRESS:
+ cc.log(event.getMessage());
+ break;
+ default:
+ break;
+ }
+ });
+ cc.eventManager.addListener(listener, 1);
+ this._am.update();
+ }
+ },
+ clickMeShowTempLayer:function () {
+ this.removeChildByTag(233, true);
+ this._tempLayer = new ScriptTestTempLayer();
+ this.addChild(this._tempLayer, 0, 233);
+ },
+ clickMeReloadTempLayer:function(){
+ cc.sys.cleanScript(tempJSFileName);
+ if (!cc.sys.isNative)
+ {
+ this.clickMeShowTempLayer();
+ }
+ else
+ {
+ this.startDownload();
+ }
+
+ },
+ onExit : function () {
+ if (this._am)
+ {
+ this._am.release();
+ this._am = null;
+ }
+
+ this._super();
+ },
+ ctor : function () {
+ this._super();
+
+ var menu = new cc.Menu();
+ menu.setPosition(cc.p(0, 0));
+ menu.width = winSize.width;
+ menu.height = winSize.height;
+ this.addChild(menu, 1);
+ var item1 = new cc.MenuItemLabel(new cc.LabelTTF("Click me show tempLayer", "Arial", 22), this.clickMeShowTempLayer, this);
+ menu.addChild(item1);
+
+ var item2 = new cc.MenuItemLabel(new cc.LabelTTF("Click me reload tempLayer", "Arial", 22), this.clickMeReloadTempLayer, this);
+ menu.addChild(item2);
+
+ menu.alignItemsVerticallyWithPadding(8);
+ menu.setPosition(cc.pAdd(cc.visibleRect.left, cc.p(+180, 0)));
+ },
+
+ getTitle : function() {
+ return "ScriptTest only used in native";
+ }
+
+});
+
+//------------------------------------------------------------------
+//
+// Restart game test
+//
+//------------------------------------------------------------------
+var RestartGameLayerTest = SysTestBase.extend({
+ getTitle : function() {
+ return "RestartGameTest only used in native";
+ },
+ restartGame:function()
+ {
+ cc.game.restart();
+ },
+ ctor : function () {
+ this._super();
+ var menu = new cc.Menu();
+ menu.setPosition(cc.p(0, 0));
+ menu.width = winSize.width;
+ menu.height = winSize.height;
+ this.addChild(menu, 1);
+ var item1 = new cc.MenuItemLabel(new cc.LabelTTF("restartGame", "Arial", 22), this.restartGame, this);
+ menu.addChild(item1);
+ menu.setPosition(cc.pAdd(cc.visibleRect.left, cc.p(+180, 0)));
+ }
+});
+
//
// Flow control
//
var arrayOfSysTest = [
-
LocalStorageTest,
CapabilitiesTest
];
+if (cc.sys.isNative && cc.sys.OS_WINDOWS != cc.sys.os) {
+ arrayOfSysTest.push(ScriptTestLayer);
+ arrayOfSysTest.push(RestartGameLayerTest);
+}
+
var nextSysTest = function () {
sysTestSceneIdx++;
sysTestSceneIdx = sysTestSceneIdx % arrayOfSysTest.length;