diff --git a/cocos/scripting/js-bindings/manual/ScriptingCore.cpp b/cocos/scripting/js-bindings/manual/ScriptingCore.cpp index 26605c0551..a9568c73ed 100644 --- a/cocos/scripting/js-bindings/manual/ScriptingCore.cpp +++ b/cocos/scripting/js-bindings/manual/ScriptingCore.cpp @@ -560,6 +560,7 @@ bool ScriptingCore::evalString(const char *string) void ScriptingCore::start() { + _engineStartTime = std::chrono::steady_clock::now(); // for now just this createGlobalContext(); } @@ -1590,6 +1591,12 @@ bool ScriptingCore::executeFunctionWithOwner(jsval owner, const char *name, cons return bRet; } +std::chrono::steady_clock::time_point ScriptingCore::getEngineStartTime() const +{ + return _engineStartTime; +} + + bool ScriptingCore::handleKeyboardEvent(void* nativeObj, cocos2d::EventKeyboard::KeyCode keyCode, bool isPressed, cocos2d::Event* event) { JSAutoCompartment ac(_cx, _global->get()); diff --git a/cocos/scripting/js-bindings/manual/ScriptingCore.h b/cocos/scripting/js-bindings/manual/ScriptingCore.h index 6b269aeb30..53ccfca22a 100644 --- a/cocos/scripting/js-bindings/manual/ScriptingCore.h +++ b/cocos/scripting/js-bindings/manual/ScriptingCore.h @@ -39,6 +39,7 @@ #include #include +#include #define ENGINE_VERSION "Cocos2d-JS v3.13" @@ -89,6 +90,8 @@ private: bool _callFromScript; ScriptingCore(); + + std::chrono::steady_clock::time_point _engineStartTime; public: ~ScriptingCore(); @@ -349,6 +352,11 @@ public: * Clean all script objects */ void cleanAllScript(); + + /**@~english + * Gets the time that the ScriptingCore was initalized + */ + std::chrono::steady_clock::time_point getEngineStartTime() const; /**@~english * Initialize everything, including the js context, js global object etc. diff --git a/cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp b/cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp index 1afde8e364..30888f5480 100644 --- a/cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp +++ b/cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp @@ -27,6 +27,7 @@ #include "scripting/js-bindings/manual/cocos2d_specifics.hpp" #include "scripting/js-bindings/auto/jsb_cocos2dx_auto.hpp" #include +#include #include "base/CCDirector.h" #include "base/CCScheduler.h" @@ -997,6 +998,17 @@ bool js_load_remote_image(JSContext *cx, uint32_t argc, jsval *vp) return false; } +using namespace std::chrono; + +bool js_performance_now(JSContext *cx, uint32_t argc, jsval *vp) +{ + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + auto now = steady_clock::now(); + auto micro = duration_cast(now - ScriptingCore::getInstance()->getEngineStartTime()).count(); + args.rval().set(DOUBLE_TO_JSVAL((double)micro * 0.001)); + return true; +} + extern JSObject* jsb_cocos2d_extension_ScrollView_prototype; extern JSObject* jsb_cocos2d_extension_TableView_prototype; extern JSObject* jsb_cocos2d_extension_Control_prototype; @@ -1041,4 +1053,8 @@ void register_all_cocos2dx_extension_manual(JSContext* cx, JS::HandleObject glob JS_DefineFunction(cx, tmpObj, "create", js_cocos2dx_CCTableView_create, 3, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(cx, jsbObj, "loadRemoteImg", js_load_remote_image, 2, JSPROP_READONLY | JSPROP_PERMANENT); + + JS::RootedObject performance(cx); + get_or_create_js_obj(cx, global, "performance", &performance); + JS_DefineFunction(cx, performance, "now", js_performance_now, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT); } diff --git a/tests/js-tests/project.json b/tests/js-tests/project.json index 283c723d47..f84c486a22 100644 --- a/tests/js-tests/project.json +++ b/tests/js-tests/project.json @@ -152,6 +152,8 @@ "src/NativeTest/NativeTest.js", "src/NativeTest/FileUtils/FileUtilsTest.js", "src/NativeTest/JSBExtendTest.js", - "src/NativeTest/AudioEngineTest.js" + "src/NativeTest/AudioEngineTest.js", + + "src/PerformanceNowTest/PerformanceNowTest.js" ] } diff --git a/tests/js-tests/src/PerformanceNowTest/PerformanceNowTest.js b/tests/js-tests/src/PerformanceNowTest/PerformanceNowTest.js new file mode 100644 index 0000000000..b46c4e160b --- /dev/null +++ b/tests/js-tests/src/PerformanceNowTest/PerformanceNowTest.js @@ -0,0 +1,164 @@ +var scenePerformanceNowTestIdx = -1; + +var PerformanceNowBaseLayer = BaseTestLayer.extend({ + ctor:function () { + this._super(cc.color(0,0,0,255), cc.color(98,99,117,255) ); + }, + + title:function () { + return "performance.now"; + }, + + subtitle:function () { + return ""; + }, + + code:function () { + return ""; + }, + + // callbacks + onRestartCallback:function (sender) { + var s = new PerformanceNowTestScene(); + s.addChild(restartPerformanceNowTest()); + director.runScene(s); + }, + onNextCallback:function (sender) { + var s = new PerformanceNowTestScene(); + s.addChild(nextPerformanceNowTest()); + director.runScene(s); + }, + onBackCallback:function (sender) { + var s = new PerformanceNowTestScene(); + s.addChild(previousPerformanceNowTest()); + director.runScene(s); + }, + + // automation + numberOfPendingTests:function() { + return ( (arrayOfPerformanceNowTest.length-1) - scenePerformanceNowTestIdx ); + }, + + getTestNumber:function() { + return scenePerformanceNowTestIdx; + } +}); + +//------------------------------------------------------------------ +// +// Tests +// +//------------------------------------------------------------------ +var BasicPerformanceNowTest = PerformanceNowBaseLayer.extend({ + onEnter:function () { + this._super(); + if (performance && typeof performance.now === 'function') { + var currentPerformanceNow = new cc.LabelTTF("Current time since start : " + performance.now()); + this.addChild(currentPerformanceNow); + currentPerformanceNow.attr({ + x: cc.winSize.width/2, + y: cc.winSize.height/2 + }); + } else { + var errLabel = new cc.LabelTTF("On browser that does not support performance.now"); + this.addChild(errLabel); + errLabel.attr({ + x: cc.winSize.width/2, + y: cc.winSize.height/2 + }); + + } + }, + + title: function() { + return "Basic performance.now functionality"; + }, + + subtitle:function () { + return "Should display number, or say not supported"; + } +}); + +var MonotonicIncreaseTest = PerformanceNowBaseLayer.extend({ + ctor:function () { + this._super(); + if (performance && typeof performance.now !== 'function') { + var errLabel = new cc.LabelTTF("On browser that does not support performance.now"); + this.addChild(errLabel); + errLabel.attr({ + x: cc.winSize.width/2, + y: cc.winSize.height/2 + }); + return; + } + + + var performanceValues = []; + for (var i = 0; i < 20; ++i) { + performanceValues.push(performance.now()); + } + + var monotonicIncrease = false; + for (var i = 1; i < performanceValues.length; ++i) { + monotonicIncrease = performanceValues[i] >= performanceValues[i - 1]; + } + + var label = new cc.LabelTTF("Result that values are montonically increasing : " + monotonicIncrease); + label.attr({ + x: cc.winSize.width/2, + y: cc.winSize.height/2 + }); + this.addChild(label); + + var values = new cc.LabelTTF("Result Values : " + JSON.stringify(performanceValues)); + values.attr({ + x: cc.winSize.width/2, + y: (cc.winSize.height/2) - 40 + }); + this.addChild(values); + + }, + + title:function () { + return "Testing monotonic increase of performance.now"; + }, + + subtitle:function () { + return "Listed values should all be increasing"; + } +}); + +var PerformanceNowTestScene = TestScene.extend({ + runThisTest:function (num) { + scenePerformanceNowTestIdx = (num || num == 0) ? (num - 1) : -1; + var layer = nextPerformanceNowTest(); + this.addChild(layer); + + director.runScene(this); + } +}); + +// +// Flow control +// +var arrayOfPerformanceNowTest = [ + BasicPerformanceNowTest, + MonotonicIncreaseTest +]; + +var nextPerformanceNowTest = function () { + scenePerformanceNowTestIdx++; + scenePerformanceNowTestIdx = scenePerformanceNowTestIdx % arrayOfPerformanceNowTest.length; + + return new arrayOfPerformanceNowTest[scenePerformanceNowTestIdx](); +}; +var previousPerformanceNowTest = function () { + scenePerformanceNowTestIdx--; + if (scenePerformanceNowTestIdx < 0) + scenePerformanceNowTestIdx += arrayOfPerformanceNowTest.length; + + return new arrayOfPerformanceNowTest[scenePerformanceNowTestIdx](); +}; +var restartPerformanceNowTest = function () { + return new arrayOfPerformanceNowTest[scenePerformanceNowTestIdx](); +}; diff --git a/tests/js-tests/src/tests-main.js b/tests/js-tests/src/tests-main.js index 83a0447bc7..0b91536fac 100644 --- a/tests/js-tests/src/tests-main.js +++ b/tests/js-tests/src/tests-main.js @@ -547,6 +547,14 @@ var testNames = [ return new PathTestScene(); } }, + { + title:"PerformanceNow Tests", + platforms: PLATFORM_ALL, + linksrc:"src/PerformanceNowTest/PerformanceNowTest.js", + testScene:function() { + return new PerformanceNowTestScene(); + } + }, { title:"Physics3D Test", platforms: PLATFORM_JSB,