diff --git a/examples/acScripts/AgentPoolControler.js b/examples/acScripts/AgentPoolControler.js new file mode 100644 index 0000000000..353480e2cf --- /dev/null +++ b/examples/acScripts/AgentPoolControler.js @@ -0,0 +1,214 @@ +// +// AgentPoolController.js +// acScripts +// +// Created by Sam Gateau on 11/23/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var COMMAND_CHANNEL = "com.highfidelity.PlaybackChannel1"; +var ANNOUNCE_CHANNEL = "com.highfidelity.playbackAgent.announceID"; + +// The time between alive messages on the command channel +var ALIVE_PERIOD = 1; + +var NUM_CYCLES_BEFORE_RESET = 5; + +// Service Actions +var AGENT_READY = "ready"; +var INVALID_ACTOR = -2; + +var MASTER_INDEX = -1; + +var MASTER_ALIVE = -1; + +function printDebug(message) { + print(message); +} + +(function() { + + var makeMessage = function(id, action, argument) { + var message = { + id_key: id, + action_key: action, + argument_key: argument + }; + return message; + }; + + var unpackMessage = function(message) { + return JSON.parse(message); + }; + + // master side + var MasterController = function() { + this.timeSinceLastAlive = 0; + this.knownAgents = new Array; + this.subscribed = false; + }; + + MasterController.prototype.reset = function() { + if (this.subscribed) { + this.timeSinceLastAlive = 0; + + } + + Messages.subscribe(COMMAND_CHANNEL); + Messages.subscribe(ANNOUNCE_CHANNEL); + + this.timeSinceLastAlive = 0; + + var localThis = this; + + Messages.messageReceived.connect(function (channel, message, senderID) { + printDebug("Agent received"); + if (channel == ANNOUNCE_CHANNEL) { + printDebug("Agent received"); + // localThis._processAgentMessage(message, senderID); + } + }); + + // ready to roll, enable + this.subscribed = true; + }; + + MasterController.prototype._processAgentMessage = function(message, senderID) { + if (message == AGENT_READY) { + + // check to see if we know about this agent + if (this.knownAgents.indexOf(senderID) < 0) { + + var indexOfNewAgent = this.knownAgents.length; + this.knownAgents[indexOfNewAgent] = senderID; + printDebug("New agent available to be hired " + senderID); + + var acknowledgeMessage = senderID + "." + indexOfNewAgent; + Messages.sendMessage(ANNOUNCE_CHANNEL, acknowledgeMessage); + } else { + + printDebug("New agent still sending ready ? " + senderID); + } + } + }; + + MasterController.prototype.destroy = function() { + if (this.subscribed) { + Messages.unsubscribe(ANNOUNCE_CHANNEL); + Messages.unsubscribe(COMMAND_CHANNEL); + this.timeSinceLastAlive = 0; + this.subscribed = true; + } + }; + + MasterController.prototype.sendCommand = function(target, action, argument) { + if (this.subscribed) { + var messageJSON = JSON.stringify(makeMessage(target, action, argument)); + Messages.sendMessage(COMMAND_CHANNEL, messageJSON); + printDebug("Master sent message: " + messageJSON); + } + }; + + MasterController.prototype.update = function(deltaTime) { + this.timeSinceLastAlive += deltaTime; + if (this.timeSinceLastAlive > ALIVE_PERIOD) { + this.timeSinceLastAlive = 0; + printDebug("Master ping alive"); + this.sendCommand(MASTER_INDEX, MASTER_ALIVE); + } + }; + + + this.MasterController = MasterController; + + // agent side + var AgentController = function() { + this.timeSinceLastAlive = 0; + this.subscribed = false; + this.actorIndex = INVALID_ACTOR; + this.notifyAlive = false; + }; + + AgentController.prototype.reset = function() { + if (!this.subscribed) { + Messages.subscribe(COMMAND_CHANNEL); + Messages.subscribe(ANNOUNCE_CHANNEL); + } + + this.timeSinceLastAlive = 0; + + var localThis = this; + Messages.messageReceived.connect(function (channel, message, senderID) { + if (channel == ANNOUNCE_CHANNEL) { + if (message != AGENT_READY) { + // this may be a message to hire me if i m not already + if (id == INVALID_ACTOR) { + var parts = message.split("."); + var agentID = parts[0]; + var actorIndex = parts[1]; + if (agentID == Agent.sessionUUID) { + // localThis.actorIndex = agentIndex; + Messages.unsubscribe(ANNOUNCE_CHANNEL); // id announce channel + } + } + } + return; + } + if (channel == COMMAND_CHANNEL) { + var command = unpackMessage(message); + printDebug("Received command = " == command); + + if (command.id_key == localThis.actorIndex || command.id_key == MASTER_INDEX) { + if (command.action_key == MASTER_ALIVE) { + // localThis.notifyAlive = true; + } else { + // localThis._processMasterMessage(command, senderID); + } + } else { + // ignored + } + return; + } + }); + + // ready to roll, enable + this.subscribed = true; + printDebug("In Reset"); + }; + + AgentController.prototype._processMasterMessage = function(command, senderID) { + printDebug("True action received = " + JSON.stringify(command) + senderID); + }; + + AgentController.prototype.update = function(deltaTime) { + this.timeSinceLastAlive += deltaTime; + if (this.timeSinceLastAlive > ALIVE_PERIOD) { + if (this.subscribed) { + printDebug("In update of client"); + if (this.actorIndex == INVALID_ACTOR) { + Messages.sendMessage(ANNOUNCE_CHANNEL, AGENT_READY); + printDebug("Client Ready"); + } else { + if (this.notifyAlive) { + this.notifyAlive = false; + printDebug("Master Alive"); + } else if (this.timeSinceLastAlive > NUM_CYCLES_BEFORE_RESET * ALIVE_PERIOD) { + printDebug("Master Lost, reseting Agent"); + this.actorIndex = UNKNOWN_AGENT_ID; + } + } + } + + this.timeSinceLastAlive = 0; + } + }; + + + this.AgentController = AgentController; +})(); + + + diff --git a/examples/acScripts/playbackAgents.js b/examples/acScripts/playbackAgents.js index 864e821175..96502a7816 100644 --- a/examples/acScripts/playbackAgents.js +++ b/examples/acScripts/playbackAgents.js @@ -8,24 +8,27 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Agent.isAvatar = true; +Script.include("./AgentPoolControler.js"); // Set the following variables to the values needed -var commandChannel = "com.highfidelity.PlaybackChannel1"; var playFromCurrentLocation = true; var useDisplayName = true; var useAttachments = true; var useAvatarModel = true; +var agentController = new AgentController(); + // ID of the agent. Two agents can't have the same ID. -var announceIDChannel = "com.highfidelity.playbackAgent.announceID"; -var UNKNOWN_AGENT_ID = -2; -var id = UNKNOWN_AGENT_ID; // unknown until aknowledged +//var UNKNOWN_AGENT_ID = -2; +//var id = UNKNOWN_AGENT_ID; // unknown until aknowledged // The time between alive messages on the command channel -var timeSinceLastAlive = 0; +/*var timeSinceLastAlive = 0; var ALIVE_PERIOD = 5; var NUM_CYCLES_BEFORE_RESET = 5; var notifyAlive = false; +*/ // Set position/orientation/scale here if playFromCurrentLocation is true Avatar.position = { x:0, y: 0, z: 0 }; @@ -118,7 +121,7 @@ function getAction(channel, message, senderID) { print("Agent #" + id + " loading clip URL is NULL, nothing happened"); } break; - case ALIVE: + case MASTER_ALIVE: print("Alive"); notifyAlive = true; break; @@ -138,10 +141,16 @@ function getAction(channel, message, senderID) { function update(deltaTime) { - + totalTime += deltaTime; + if (totalTime > WAIT_FOR_AUDIO_MIXER) { + if (!agentController.subscribed) { + agentController.reset(); + } + } + /* + totalTime += deltaTime; - - if (totalTime > WAIT_FOR_AUDIO_MIXER) { + if (totalTime > WAIT_FOR_AUDIO_MIXER) { if (!subscribed) { Messages.subscribe(commandChannel); // command channel Messages.subscribe(announceIDChannel); // id announce channel @@ -168,9 +177,11 @@ function update(deltaTime) { Agent.isAvatar = false; id = UNKNOWN_AGENT_ID; } - } -} + }*/ + agentController.update(deltaTime); +} +/* Messages.messageReceived.connect(function (channel, message, senderID) { if (channel == announceIDChannel && message != "ready") { // If I don't yet know if my ID has been recieved, then check to see if the master has acknowledged me @@ -187,6 +198,13 @@ Messages.messageReceived.connect(function (channel, message, senderID) { if (channel == commandChannel) { getAction(channel, message, senderID); } -}); +});*/ + +function scriptEnding() { + + agentController.destroy(); +} + Script.update.connect(update); +Script.scriptEnding.connect(scriptEnding); diff --git a/examples/acScripts/playbackMaster.js b/examples/acScripts/playbackMaster.js index 2c9d4f77eb..eb7f86518f 100644 --- a/examples/acScripts/playbackMaster.js +++ b/examples/acScripts/playbackMaster.js @@ -8,30 +8,22 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("./AgentPoolControler.js"); HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +var masterController = new MasterController(); var ac_number = 1; // This is the default number of ACs. Their ID need to be unique and between 0 (included) and ac_number (excluded) var names = new Array(); // It is possible to specify the name of the ACs in this array. ACs names ordered by IDs (Default name is "ACx", x = ID + 1)) -var commandChannel = "com.highfidelity.PlaybackChannel1"; -var subscribed = false; var input_text = null; -var knownAgents = new Array; // We will add our known agents here when we discover them - -// available playbackAgents will announce their sessionID here. -var announceIDChannel = "com.highfidelity.playbackAgent.announceID"; - -// The time between alive messages on the command channel -var timeSinceLastAlive = 0; -var ALIVE_PERIOD = 5; // Script. DO NOT MODIFY BEYOND THIS LINE. //Script.include("../libraries/toolBars.js"); Script.include(HIFI_PUBLIC_BUCKET + "scripts/libraries/toolBars.js"); -var ALIVE = -1; + var DO_NOTHING = 0; var PLAY = 1; var PLAY_LOOP = 2; @@ -67,9 +59,8 @@ function setupPlayback() { if (ac_number === "" || ac_number === null) { ac_number = 1; } - Messages.subscribe(commandChannel); - subscribed = true; setupToolBars(); + masterController.reset(); } function setupToolBars() { @@ -180,7 +171,6 @@ function sendCommand(id, action, argument) { toolBars[id].setAlpha(ALPHA_OFF, playLoopIcon[id]); toolBars[id].setAlpha(ALPHA_OFF, stopIcon[id]); toolBars[id].setAlpha(ALPHA_OFF, loadIcon[id]); - } else if (action == ALIVE) { } else if (toolBars[id].toolSelected(onOffIcon[id])) { return; } @@ -199,6 +189,8 @@ function sendCommand(id, action, argument) { } else { id = -1; + masterController.sendMessage(id, action, argument); + /* var message = { id_key: id, action_key: action, @@ -208,10 +200,11 @@ function sendCommand(id, action, argument) { if(subscribed){ Messages.sendMessage(commandChannel, JSON.stringify(message)); print("Message sent!"); - } + }*/ } } else { - + masterController.sendMessage(id, action, argument); + /* var message = { id_key: id, action_key: action, @@ -221,7 +214,7 @@ function sendCommand(id, action, argument) { if(subscribed){ Messages.sendMessage(commandChannel, JSON.stringify(message)); print("Message sent!"); - } + }*/ } } @@ -303,12 +296,7 @@ function update(deltaTime) { performanceLoadedNeedUpdate = false; } - timeSinceLastAlive += deltaTime; - if (timeSinceLastAlive > ALIVE_PERIOD) { - timeSinceLastAlive = 0; - print("ping alive"); - sendCommand((toolBars.length - 1), ALIVE); - } + masterController.update(deltaTime); } function scriptEnding() { @@ -317,10 +305,7 @@ function scriptEnding() { Overlays.deleteOverlay(nameOverlays[i]); } - if (subscribed) { - Messages.unsubscribe(commandChannel); - } - Messages.unsubscribe(announceIDChannel); + masterController.destroy(); } Controller.mousePressEvent.connect(mousePressEvent); @@ -328,7 +313,7 @@ Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); - +/* Messages.subscribe(announceIDChannel); Messages.messageReceived.connect(function (channel, message, senderID) { if (channel == announceIDChannel && message == "ready") { @@ -348,5 +333,5 @@ Messages.messageReceived.connect(function (channel, message, senderID) { } }); - +*/ moveUI();