define([ "Game/Channel/GameController", "Lib/Utilities/NotificationCenter", "Game/Channel/User", "Lib/Utilities/Protocol/Helper", "Lib/Utilities/Options", "Game/Config/Settings" ], function (GameController, Nc, User, ProtocolHelper, Options, Settings) { function Channel (pipeToServer, options) { var self = this; this.options = options = Options.merge(options, { levelUids: Settings.DEFAULT_LEVELS }); this.name = options.channelName; this.users = {}; this.pipeToServer = pipeToServer; this.gameController = new GameController(this); Nc.on('channel/controlCommand', function (message) { ProtocolHelper.applyCommand(message.data, self); }); Nc.on('broadcastControlCommand', this.broadcastControlCommand, this); Nc.on('broadcastControlCommandExcept', this.broadcastControlCommandExcept, this); Nc.on('broadcastGameCommand', this.broadcastGameCommand, this); Nc.on('broadcastGameCommandExcept', this.broadcastGameCommandExcept, this); console.checkpoint('channel ' + this.name + ' created'); setTimeout(function() { if(Object.keys(self.users).length < 1) { self.destroy(); } }, Settings.CHANNEL_DESTRUCTION_TIME * 1000); } // Channel command callbacks Channel.prototype.onAddUser = function (userId) { var self = this; if(!this.gameController.level || !this.gameController.level.isLoaded) { var token = Nc.on("game/level/loaded", function() { self.sendJoinSuccess(userId); Nc.off(token); }); } else { self.sendJoinSuccess(userId); } } Channel.prototype.sendJoinSuccess = function(userId) { var user = new User(userId, this); var joinedUsers = Object.keys(this.users); var levelUid = null; if(this.gameController.level) { levelUid = this.gameController.level.uid; } this.users[user.id] = user; var options = { userId: user.id, channelName: this.name, joinedUsers: joinedUsers, levelUid: levelUid }; Nc.trigger('user/' + user.id + "/joinSuccess", options); Nc.trigger('user/joined', user); }; Channel.prototype.onReleaseUser = function (userId) { var user = this.users[userId]; Nc.trigger('user/left', userId); delete this.users[userId]; this.broadcastControlCommand("userLeft", userId); // FIXME: if this was the last user terminate forked process if(Object.keys(this.users).length < 1) { this.destroy(); } } Channel.prototype.destroy = function() { console.checkpoint("channel (" + this.name + ") destroyed"); this.pipeToServer.destroy(); }; // Sending commands Channel.prototype.broadcastControlCommand = function (command, options) { for(var id in this.users) { this.users[id].sendControlCommand(command, options); } } Channel.prototype.broadcastControlCommandExcept = function (command, options, exceptUser) { for(var id in this.users) { if (id != exceptUser.id) { this.users[id].sendControlCommand(command, options); } } } Channel.prototype.broadcastGameCommand = function (command, options) { for(var id in this.users) { this.users[id].sendGameCommand(command, options); } } Channel.prototype.broadcastGameCommandExcept = function (command, options, exceptUser) { for(var id in this.users) { if (id != exceptUser.id) { this.users[id].sendGameCommand(command, options); } } } return Channel; });