Skip to content
This repository has been archived by the owner on Jan 13, 2022. It is now read-only.

Commit

Permalink
Results are now persisted and can be viewed
Browse files Browse the repository at this point in the history
  • Loading branch information
nincode committed Jul 8, 2011
1 parent 721d111 commit 94a1b8a
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 10 deletions.
12 changes: 9 additions & 3 deletions engine/core/browser.js
Expand Up @@ -35,8 +35,13 @@ var Browser = (function() {
} }


function detect() { function detect() {
var user_agent = navigator.userAgent.toLowerCase(); var user_agent = navigator.userAgent;
Browser.browser_version = detectFromUA(user_agent);
console.log('browser_version ' + Browser.browser_version);
}


function detectFromUA(user_agent) {
user_agent = user_agent.toLowerCase();
if (/chrome/.test(user_agent)) { if (/chrome/.test(user_agent)) {
Browser.browser = Browser.CHROME; Browser.browser = Browser.CHROME;
Browser.threeD = true; Browser.threeD = true;
Expand Down Expand Up @@ -147,8 +152,8 @@ var Browser = (function() {
} }
break; break;
} }
Browser.browser_version = Browser.os + ' ' + Browser.browser_version; var retVal = Browser.os + ' ' + Browser.browser_version;
console.log('browser_version ' + Browser.browser_version); return retVal;
} }


function getWindowSize() { function getWindowSize() {
Expand Down Expand Up @@ -176,5 +181,6 @@ var Browser = (function() {


Browser.getWindowSize = getWindowSize; Browser.getWindowSize = getWindowSize;
Browser.detect = detect; Browser.detect = detect;
Browser.detectFromUA = detectFromUA;
return Browser; return Browser;
})(); })();
107 changes: 107 additions & 0 deletions lib/benchmark.js
@@ -0,0 +1,107 @@
// Copyright 2004-present Facebook. All Rights Reserved.

// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.


var benchmark_results = new Array();
var benchmark_file_name = 'benchmark_results.json';
var results_to_keep = 10000;
var results_to_return = 20;

function benchmarkResult(time, result, browser, testData) {
this.time = time;
this.result = result;
this.browser = browser;
this.testData = testData;
}

function resultSorterByTopScore(a, b) {
return b.result - a.result;
}

function resultSorterByNewest(a, b) {
return b.time - a.time;
}

function processResult(result, browser, testData) {
var time = new Date();
var br = new benchmarkResult(time.valueOf(), result, browser, testData);
benchmark_results.push(br);
benchmark_results.sort(resultSorterByNewest);
if (benchmark_results.length > results_to_keep) {
benchmark_results.splice(results_to_keep, benchmark_results.length);
}
}

function saveResults() {
fs.writeFileSync(benchmark_file_name, JSON.stringify(benchmark_results));
console.log('BenchmarkResult - saved '+benchmark_results.length+' results');
}

function loadResults() {
var data;
try {
data = fs.readFileSync(benchmark_file_name);
} catch(err) {
return;
}
if (data.length > 0) {
benchmark_results = JSON.parse(data);
}
console.log('BenchmarkResult - loaded '+benchmark_results.length+' results');
}

function init() {
if (benchmark_results.length == 0)
loadResults();
}

function getTopResults()
{
var ret = benchmark_results;
ret.sort(resultSorterByTopScore);
//ret.splice(results_to_return, ret.length);

// Convert results into something the client can use - strip out extra
// headers bits, etc.
var results = new Array();
var total_results = Math.min(results_to_return, ret.length);
for (var i=0; i<total_results; i++) {
results[i] = {};
if ("user-agent" in ret[i].browser) {
results[i].browser = ret[i].browser["user-agent"];
} else {
results[i].browser = ret[i].browser;
}
results[i].time = ret[i].time;
results[i].score = ret[i].result;
}
return results;
}

function testResults() {
return;
if (benchmark_results.length>5)
return;
processResult(Math.floor(Math.random()*50), "Chrome", "relja");
processResult(Math.floor(Math.random()*50), "Chrome", "relja");
processResult(Math.floor(Math.random()*50), "Chrome <script>foo!<script>i &bla=noway", "relja");
processResult(Math.floor(Math.random()*50), "Chrome &bla=bla", "relja");
processResult(Math.floor(Math.random()*50), "IE10", "relja");
}

exports.init = init;
exports.test = testResults;
exports.save = saveResults;
exports.getTopResults = getTopResults;
exports.processResult = processResult;
31 changes: 24 additions & 7 deletions lib/server.js
Expand Up @@ -12,6 +12,8 @@
// License for the specific language governing permissions and limitations // License for the specific language governing permissions and limitations
// under the License. // under the License.


BenchmarkResults = require('../lib/benchmark.js');

var tick_count = 0; var tick_count = 0;
var tick_fps = 50; var tick_fps = 50;
var grid_send_rate = 5; // needs to be integer multiple of tick_fps var grid_send_rate = 5; // needs to be integer multiple of tick_fps
Expand Down Expand Up @@ -52,6 +54,7 @@ function init() {
} }
}); });
setInterval(function() { tick(); }, 1000 / tick_fps); setInterval(function() { tick(); }, 1000 / tick_fps);
BenchmarkResults.init();
} }


function listen(port,options,cb) { function listen(port,options,cb) {
Expand Down Expand Up @@ -171,23 +174,37 @@ function postHandler(request, callback) {
}; };


function serverCallback(req, res) { function serverCallback(req, res) {
var parse = url.parse(req.url);
var pathname = parse.pathname || '/';
var split = pathname.split('/');
if (req.method == 'POST') { if (req.method == 'POST') {
//console.log(req.method + ': ' + req.url); console.log(req.method + ': ' + req.url);
//console.log('headers: ' + JSON.stringify(req.headers)); console.log('headers: ' + JSON.stringify(req.headers));
//console.log('body: ' + JSON.stringify(req.body)); console.log('body: ' + JSON.stringify(req.body));
postHandler(req, function(data) { postHandler(req, function(data) {
if (data.indexOf('cmd:') == 0) { if (data.indexOf('cmd:') == 0) {
var fb_info = Graph.fbinfo_from_cookie(req.headers.cookie); var fb_info = Graph.fbinfo_from_cookie(req.headers.cookie);
console.log(JSON.stringify(fb_info)); console.log(JSON.stringify(fb_info));
Graph.handler(fb_info,res,data.substring(5)); Graph.handler(fb_info,res,data.substring(5));
} else { } else {
console.log(data); var result = JSON.parse(data);
BenchmarkResults.processResult(result.score, req.headers, result.testName);
res.writeHead(200, {'Content-Type': 'text/html'});
res.end();
BenchmarkResults.save();
return;
} }
}); });
} else {
if (split[1] === 'benchmark_results') {
res.writeHead(200, {'Content-Type': 'text/html'});
var returnData = JSON.stringify(BenchmarkResults.getTopResults());
res.write(returnData);
res.end();
return;
}
} }
var parse = url.parse(req.url);
var pathname = parse.pathname || '/';
var split = pathname.split('/');
if (0 && req.method === 'POST') { if (0 && req.method === 'POST') {
console.log('headers: ' + JSON.stringify(req.headers)); console.log('headers: ' + JSON.stringify(req.headers));
switch(split[1]) { switch(split[1]) {
Expand Down
21 changes: 21 additions & 0 deletions perf/css/perf.css
Expand Up @@ -763,3 +763,24 @@ to { -webkit-transform: translate3d(-50px,-50px,200px) rotateZ(360deg); }
#details { #details {
overflow: auto; overflow: auto;
} }

.bar {
background-color: #98F5FF;
position: relative;
height: 16px;
margin-top: 1px;
margin-bottom: 1px;
-moz-box-shadow: 5px 5px 5px #008;
-webkit-box-shadow: 5px 5px 5px #008;
box-shadow: 5px 5px 5px #008;
}

table.hpadding td {
padding-right: 10px;
text-align: left;
}

table.hpadding th {
padding-right: 10px;
text-align: left;
}
1 change: 1 addition & 0 deletions perf/index.shtml
Expand Up @@ -5,6 +5,7 @@
<script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript" src="/socket.io/socket.io.js"></script>
#include '/engine/include/core.include' #include '/engine/include/core.include'
<link rel="stylesheet" type="text/css" href="/perf/css/perf.css" /> <link rel="stylesheet" type="text/css" href="/perf/css/perf.css" />
<script type="text/javascript" src="/engine/core/xhr.js"> </script>
<script type="text/javascript" src="/perf/benchmark.js"> </script> <script type="text/javascript" src="/perf/benchmark.js"> </script>
<script type="text/javascript" src="/perf/perftest.js"> </script> <script type="text/javascript" src="/perf/perftest.js"> </script>
<script type="text/javascript" src="/perf/fbmark.js"> </script> <script type="text/javascript" src="/perf/fbmark.js"> </script>
Expand Down
77 changes: 77 additions & 0 deletions perf/perf.js
Expand Up @@ -182,6 +182,76 @@ var Perf = (function() {
} }
} }


// Score reporting
function getBrowser() {
var b = data.browser;
var browser = b.match(/(\w+) \d+/);
if (browser) {
browser = browser[1];
} else {
browser = b;
}
}

function getScores() {
var req = new XMLHttpRequest();
req.open('GET', 'benchmark_results', true);
req.onreadystatechange = function() {
var result;
var done = 4, ok = 200;
if (req.readyState == done && req.status == ok) {
result = JSON.parse(req.responseText);
outputScoresAsync(result);
}
}
req.send(null);
return "Loading result history...";
}

// Super hacky and likely unsafe sanitization function
// Still looking for the best way to sanitize strings in node.js
function sanitize(string) {
return string.replace(/[&<>]/g, '');
}

function outputScoresAsync(results) {
var scoreTable;
var maxResult;

scoreTable='<table class="hpadding">';
scoreTable+='<tr><th style="width:200px"></th><th>Score</th><th>Browser</th><th>Date</th></tr>';

if (results.length>0) {
maxResult = parseInt(results[0].score);
}

for (var i=0; i<results.length; i++) {
var date = new Date(results[i].time).toDateString();
var score = parseInt(results[i].score);
var barWidth = score*100/maxResult;
scoreTable+='<tr>';
scoreTable+='<td><div class="bar" style="width:'+barWidth+'%;"></div></td>';
scoreTable+='<td>'+score+'</td>';
scoreTable+='<td>'+sanitize(Browser.detectFromUA(results[i].browser))+'</td>';
scoreTable+='<td>'+sanitize(date)+'</td>';
scoreTable+='</tr>';
}
scoreTable+='</table>';

UI.addHTML('details', 'detailinfo', {pos: [5, 105], uiclass: 'renderdetails', markup: scoreTable});
}

function showHiscores() {
UI.del('details');
UI.addCollection('perf', 'details', {uiclass: 'perfblock', pos: [265, 0], width: 600, height: 1000});

var score = 'All time high scores:';
UI.addHTML('details', 'dperfscore', {pos: [3, 4], uiclass: 'perfscore', markup: score});

getScores();
}


function canvasDemo() { function canvasDemo() {
UI.del('buttons'); UI.del('buttons');
UI.del('perf'); UI.del('perf');
Expand Down Expand Up @@ -358,6 +428,9 @@ var Perf = (function() {
// UI.addButton('buttons', 'idemo', {pos: [530, 5], width: 95, height: 40, text: 'iPhone Demo', command: {cmd: 'idemo', args: []}}); // UI.addButton('buttons', 'idemo', {pos: [530, 5], width: 95, height: 40, text: 'iPhone Demo', command: {cmd: 'idemo', args: []}});
// UI.addButton('buttons', 'rotdemo', {pos: [635, 5], width: 95, height: 40, text: 'Rotate Demo', command: {cmd: 'rotdemo', args: []}}); // UI.addButton('buttons', 'rotdemo', {pos: [635, 5], width: 95, height: 40, text: 'Rotate Demo', command: {cmd: 'rotdemo', args: []}});
UI.addCollection(null, 'perf', {pos: [100, 60], width: 260}); UI.addCollection(null, 'perf', {pos: [100, 60], width: 260});
UI.addButton('buttons', 'hiscore', {pos: [540, 5], width: 95, height: 40, text: 'Hi-Scores', command: {cmd: 'showHiscores', args: []}});


if (data) { if (data) {
for (var i = 0, len = data.length; i < len; i++) { for (var i = 0, len = data.length; i < len; i++) {
UI.addCollection('perf', 'perfblock' + i, {uiclass: 'perfblock', pos: [0, 82 * i], height: 78, width: 260, command: {cmd:'showdetails', args:[data[i]]}}); UI.addCollection('perf', 'perfblock' + i, {uiclass: 'perfblock', pos: [0, 82 * i], height: 78, width: 260, command: {cmd:'showdetails', args:[data[i]]}});
Expand All @@ -372,6 +445,9 @@ var Perf = (function() {
var score = parseInt(data[i].peak); var score = parseInt(data[i].peak);
UI.addHTML('perfblock' + i, 'perfscore' + i, {pos: [5, 24], uiclass: 'perfscore', markup: score}); UI.addHTML('perfblock' + i, 'perfscore' + i, {pos: [5, 24], uiclass: 'perfscore', markup: score});
} }

// Display result browser
showHiscores();
} }
} }


Expand All @@ -390,6 +466,7 @@ var Perf = (function() {
ClientCmd.install('idemo', iDemo); ClientCmd.install('idemo', iDemo);
ClientCmd.install('rotdemo', rotDemo); ClientCmd.install('rotdemo', rotDemo);
ClientCmd.install('scrolldemo', scrollDemo); ClientCmd.install('scrolldemo', scrollDemo);
ClientCmd.install('showHiscores', showHiscores);
ClientCmd.install('playgame', playGame); ClientCmd.install('playgame', playGame);
ClientCmd.install('playgamehtml', playGameHTML); ClientCmd.install('playgamehtml', playGameHTML);
ClientCmd.install('showdetails', showDetails); ClientCmd.install('showdetails', showDetails);
Expand Down
10 changes: 10 additions & 0 deletions perf/perftest.js
Expand Up @@ -368,6 +368,15 @@ var PerfTest = (function() {


var current = 0; var current = 0;


PerfTest.postToServer = function(score, testName) {
var req = new XMLHttpRequest();
req.open('POST', 'benchmark_results', false);
var result={};
result.score=score;
result.testName=testName;
req.send(JSON.stringify(result));
}

PerfTest.init = function() { PerfTest.init = function() {
UI.del('buttons'); UI.del('buttons');
UI.del('perf'); UI.del('perf');
Expand Down Expand Up @@ -441,6 +450,7 @@ var PerfTest = (function() {
temp.peak = result.score; temp.peak = result.score;
FBmark.reset(); FBmark.reset();
PerfTest.stop(); PerfTest.stop();
PerfTest.postToServer(result.score, [temp]);
ClientCmd.perfdisplay([temp]); ClientCmd.perfdisplay([temp]);
} }
} }
Expand Down

0 comments on commit 94a1b8a

Please sign in to comment.