Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions modules/devkit-simulator-client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,30 @@ exports.onLaunch = function () {
GLOBAL.NATIVE.onBackButton && GLOBAL.NATIVE.onBackButton(evt);
});

/** Puts preserveCache on localStorage so that jsio knows to preserve (and then request)
suggestions next load. Optionally also sets partialLoad, which causes jsio to wait for
a partialLoadContinue signal to actually load the app, after preloading suggestions. */
channel.on('reload', function (data, req) {
localStorage.setItem(jsio.__env.getNamespace('preserveCache'), true);

if (data) {
if (data.partialLoad) {
localStorage.setItem(jsio.__env.getNamespace('partialLoad'), true);
}
}

req.send(true);
});

/** partialLoadContinue is to be used in conjunction with partialLoad */
channel.on('partialLoadContinue', function (data, req) {
var def = window._continueLoadDefer;
if (def) {
def.resolve();
}
req.send(true);
});

channel.on('screenshot', function (data, req) {
devkit.debugging.screenshot(function (err, res) {
if (err) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"bluebird": "^2.9.24",
"body-parser": "1.x",
"chalk": "^1.0.0",
"chokidar": "^1.0.5",
"compression": "^1.4.3",
"express": "4.x",
"ff": "^0.2.1",
Expand Down
3 changes: 1 addition & 2 deletions src/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,8 @@ exports.build = function (appPath, argv, cb) {
// ONLY print config to stdout
process.stdout.write(JSON.stringify(merge({title: app.manifest.title}, config)));
process.exit(0);
} else {
require('./steps/logConfig').log(app, config, f());
}
require('./steps/logConfig').log(app, config, f());
}, function () {
require('./steps/executeTargetBuild').build(app, config, f());
}, function () {
Expand Down
155 changes: 145 additions & 10 deletions src/serve/appRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ var jvmtools = require('../jvmtools');
var logging = require('../util/logging');
var buildQueue = require('./buildQueue');

var chokidar = require('chokidar');

var logger = logging.get('routes');

var HOME = process.env.HOME
|| process.env.HOMEPATH
|| process.env.USERPROFILE;
var ROUTE_INACTIVE_TIME_LIMIT = 30 * 60 * 1000;

exports.addToAPI = function (opts, api) {

Expand Down Expand Up @@ -53,6 +56,7 @@ exports.addToAPI = function (opts, api) {
res.json(mountInfo);
})
.catch(function (e) {
logger.error('Error mounting app', e.stack);
res.status(500).send({
message: e.message,
stack: e.stack
Expand All @@ -70,13 +74,13 @@ exports.addToAPI = function (opts, api) {
return mountAppFromRequest(opts)
.then(function (mountInfo) {
var buildOpts = {
target: opts.target,
scheme: opts.scheme,
simulated: true,
simulateDeviceId: opts.deviceId,
simulateDeviceType: opts.deviceType,
output: mountInfo.buildPath
};
target: opts.target,
scheme: opts.scheme,
simulated: true,
simulateDeviceId: opts.deviceId,
simulateDeviceType: opts.deviceType,
output: mountInfo.buildPath
};

return buildQueue
.add(mountInfo.appPath, buildOpts)
Expand Down Expand Up @@ -133,24 +137,95 @@ exports.addToAPI = function (opts, api) {
});
}

// Promises that resolve with mount info once ready
var _mountedApps = {};
// Map of appId -> app
var _availableSimulatorApps = {};
var getAppByPath = function(appPath) {
for (var appId in _availableSimulatorApps) {
var app = _availableSimulatorApps[appId];
if (app.appPath === appPath) {
return app;
}
}
return null;
};

baseApp.use('/apps/:appId', function(req, res, next) {
var app = _availableSimulatorApps[req.params.appId];
if (app) {
app(req, res, next);
} else {
next();
}
});

baseApp.io.on('connection', function(socket) {
logger.info('socket connected');

socket.on('watch', function(appPath) {
// Add this socket to the app
var app = getAppByPath(appPath);
if (app) {
app.sockets.push(socket);
}
});

socket.on('disconnect', function() {
logger.info('socket disconnect');
});

});

function mountApp(appPath, buildPath) {
var routeId = generateRouteId(appPath);

if (!_mountedApps[appPath]) {
_mountedApps[appPath] = apps.get(appPath)
.then(function mountExtensions(app) {
var routeId = generateRouteId(appPath);
var simulatorApp = express();
baseApp.use('/apps/' + routeId, simulatorApp);

// Special case src directories
simulatorApp.use(
'/modules',
express.static(path.join(appPath, 'modules'))
);
simulatorApp.use(
'/src',
express.static(path.join(appPath, 'src'))
);
simulatorApp.use(
'/resources',
express.static(path.join(appPath, 'resources'))
);

// Static serve builds
simulatorApp.use('/', express.static(buildPath));

addSimulatorAPI(simulatorApp);

var modules = app.getModules();
var debuggerURLs = {};
var simulatorURLs = {};
var loadExtension = function (module) {
// All modules get a chance to add "resources" routes
var buildExtension = module.loadExtension('build');
if (buildExtension) {
var resources = buildExtension.getResourceDirectories();
if (resources) {
var prefix = '/modules/' + module.name;
resources.forEach(function(resource) {
simulatorApp.use(
path.join(prefix, resource.target),
express.static(resource.src)
);
});
}
}

var extension = module.loadExtension('debugger');
if (!extension || !extension.getMiddleware) { return; }

try {
var routes = extension.getMiddleware(require('../api'), app);
if (!routes) { return; }
Expand Down Expand Up @@ -181,6 +256,35 @@ exports.addToAPI = function (opts, api) {

baseModules.forEach(function (module) { loadExtension(module); });

// Add socket connection
simulatorApp.sockets = [];
simulatorApp.socketEmit = function(name, data) {
simulatorApp.sockets.forEach(function(socket) {
socket.emit(name, data);
});
};

// Everything is set, add some file watchers
simulatorApp.watchers = [];
simulatorApp.watchers.push(
chokidar.watch(
[
path.join(appPath, 'manifest.json'),
path.join(appPath, 'src'),
path.join(appPath, 'resources')
],
{ recursive: true, followSymLinks: false, persistent: true, ignoreInitial: true }
).on('all', function(event, path) {
logger.info(routeId + ': changed ' + path);
simulatorApp.socketEmit('watch:changed', path);
})
);

// Meta data
simulatorApp.appPath = appPath;

// Add to available routes, return info
_availableSimulatorApps[routeId] = simulatorApp;
return {
id: routeId,
url: '/apps/' + routeId + '/',
Expand All @@ -192,7 +296,38 @@ exports.addToAPI = function (opts, api) {
});
}

return Promise.resolve(_mountedApps[appPath]);
// Remove and clean up the routes after a bit of inactivity
var mountedApp = _mountedApps[appPath];
// remove the old timeout
if (mountedApp.cleanupTimeout) {
clearTimeout(mountedApp.cleanupTimeout);
}
mountedApp.cleanupTimeout = setTimeout(
unmountApp.bind(null, appPath, routeId),
ROUTE_INACTIVE_TIME_LIMIT
);

return Promise.resolve(mountedApp);
}

function unmountApp(appPath, routeId) {
logger.info('Shutting down route for: ' + appPath + ' (' + routeId + ')');

var app = _availableSimulatorApps[routeId];

// Close sockets
app.sockets.forEach(function(socket) {
socket.disconnect();
});

// Remove watchers
app.watchers.forEach(function(watcher) {
watcher.close();
});

// Remove app routes
delete _availableSimulatorApps[routeId];
delete _mountedApps[appPath];
}

// tracks used route uuids
Expand Down
6 changes: 2 additions & 4 deletions src/serve/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,11 @@ var Z_BEST_COMPRESSION = 9;
exports.serveWeb = function (opts, cb) {
var port = opts.port;

// common.track("BasilServe");
var app = express();
var server = http.Server(app);

app.io = require('socket.io')(server);

// var deviceManager = require('./deviceManager').get();
// deviceManager.init(app.io);

app.use(compression({level: Z_BEST_COMPRESSION}));

app.use(function noCacheControl(req, res, next) {
Expand All @@ -54,6 +50,8 @@ exports.serveWeb = function (opts, cb) {
app.use('/compile/', importMiddleware(getPath('static/')));

// serve static files
var devkitPath = path.resolve(__dirname, '..', '..');
app.use('/devkit/', express.static(devkitPath));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels a little excessive, do we need to serve the entire devkit directory?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Serving the entire thing because its part of the available path ingame, I
think. If we don't need devkit on the games path, we don't have to serve
the whole thing (or if there are specific subpaths)
On Jul 29, 2015 1:23 PM, "Martin Hunt" notifications@github.com wrote:

In src/serve/index.js
#238 (comment):

@@ -54,6 +50,8 @@ exports.serveWeb = function (opts, cb) {
app.use('/compile/', importMiddleware(getPath('static/')));

// serve static files

  • var devkitPath = path.resolve(__dirname, '..', '..');
  • app.use('/devkit/', express.static(devkitPath));

this feels a little excessive, do we need to serve the entire devkit
directory?


Reply to this email directly or view it on GitHub
https://github.com/gameclosure/devkit/pull/238/files#r35807066.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really? I thought only module code was available, and then only the folders specified in a module's package config.

app.use('/', express.static(getPath('static')));

// Serve
Expand Down
Loading