Adding performance.now() to cocos2d-js. (#16766)

* Adding performance.now() to cocos2d-js. See https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

* Fixing improper logic for converting from microseconds, to milliseconds with micro-precision

* Adding performance.now tests
This commit is contained in:
David DeSimone 2016-11-03 20:58:48 -07:00 committed by minggo
parent fa02f24f0d
commit 9204c87cfc
6 changed files with 206 additions and 1 deletions

View File

@ -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());

View File

@ -39,6 +39,7 @@
#include <assert.h>
#include <memory>
#include <chrono>
#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.

View File

@ -27,6 +27,7 @@
#include "scripting/js-bindings/manual/cocos2d_specifics.hpp"
#include "scripting/js-bindings/auto/jsb_cocos2dx_auto.hpp"
#include <thread>
#include <chrono>
#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<microseconds>(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);
}

View File

@ -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"
]
}

View File

@ -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]();
};

View File

@ -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,