mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 18:55:01 +02:00
Merge pull request #6480 from samcake/controllers
Playback: Trying to get the Agent to Master connection more reliable
This commit is contained in:
commit
ba0ce5f3b3
3 changed files with 812 additions and 302 deletions
416
examples/acScripts/AgentPoolController.js
Normal file
416
examples/acScripts/AgentPoolController.js
Normal file
|
@ -0,0 +1,416 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
function printDebug(message) {
|
||||
print(message);
|
||||
}
|
||||
|
||||
(function() {
|
||||
var SERVICE_CHANNEL = "com.highfidelity.playback.service";
|
||||
var COMMAND_CHANNEL = "com.highfidelity.playback.command";
|
||||
|
||||
// The time between alive messages on the command channel
|
||||
var ALIVE_PERIOD = 3;
|
||||
var NUM_CYCLES_BEFORE_RESET = 8;
|
||||
|
||||
// Service Actions
|
||||
var MASTER_ID = -1;
|
||||
var INVALID_AGENT = -2;
|
||||
|
||||
var BROADCAST_AGENTS = -3;
|
||||
|
||||
var MASTER_ALIVE = "MASTER_ALIVE";
|
||||
var AGENT_ALIVE = "AGENT_ALIVE";
|
||||
var AGENT_READY = "READY";
|
||||
var MASTER_HIRE_AGENT = "HIRE"
|
||||
var MASTER_FIRE_AGENT = "FIRE";
|
||||
|
||||
var makeUniqueUUID = function(SEUUID) {
|
||||
//return SEUUID + Math.random();
|
||||
// forget complexity, just give me a four digit pin
|
||||
return (Math.random() * 10000).toFixed(0);
|
||||
}
|
||||
|
||||
var packServiceMessage = function(dest, command, src) {
|
||||
var message = {
|
||||
dest: dest,
|
||||
command: command,
|
||||
src: src
|
||||
};
|
||||
return JSON.stringify(message);
|
||||
};
|
||||
|
||||
var unpackServiceMessage = function(message) {
|
||||
return JSON.parse(message);
|
||||
};
|
||||
|
||||
var packCommandMessage = function(dest, action, argument) {
|
||||
var message = {
|
||||
dest_key: dest,
|
||||
action_key: action,
|
||||
argument_key: argument
|
||||
};
|
||||
return JSON.stringify(message);
|
||||
};
|
||||
|
||||
var unpackCommandMessage = function(message) {
|
||||
return JSON.parse(message);
|
||||
};
|
||||
|
||||
// Actor
|
||||
//---------------------------------
|
||||
var Actor = function() {
|
||||
this.agentID = INVALID_AGENT;
|
||||
this.lastAliveCycle = 0;
|
||||
this.onHired = function(actor) {};
|
||||
this.onFired = function(actor) {};
|
||||
};
|
||||
|
||||
Actor.prototype.isConnected = function () {
|
||||
return (this.agentID != INVALID_AGENT);
|
||||
}
|
||||
|
||||
Actor.prototype.alive = function () {
|
||||
printDebug("Agent UUID =" + this.agentID + " Alive was " + this.lastAliveCycle);
|
||||
this.lastAliveCycle = 0;
|
||||
}
|
||||
Actor.prototype.incrementAliveCycle = function () {
|
||||
printDebug("Actor.prototype.incrementAliveCycle UUID =" + this.agentID + " Alive pre increment " + this.lastAliveCycle);
|
||||
if (this.isConnected()) {
|
||||
this.lastAliveCycle++;
|
||||
printDebug("Agent UUID =" + this.agentID + " Alive incremented " + this.lastAliveCycle);
|
||||
}
|
||||
return this.lastAliveCycle;
|
||||
}
|
||||
|
||||
this.Actor = Actor;
|
||||
|
||||
// master side
|
||||
//---------------------------------
|
||||
var MasterController = function() {
|
||||
this.timeSinceLastAlive = 0;
|
||||
this.knownAgents = new Array;
|
||||
this.hiredActors = new Array;
|
||||
this.hiringAgentsQueue = new Array;
|
||||
this.subscribed = false;
|
||||
};
|
||||
|
||||
MasterController.prototype.destroy = function() {
|
||||
if (this.subscribed) {
|
||||
Messages.unsubscribe(SERVICE_CHANNEL);
|
||||
Messages.unsubscribe(COMMAND_CHANNEL);
|
||||
this.subscribed = true;
|
||||
}
|
||||
};
|
||||
|
||||
MasterController.prototype.reset = function() {
|
||||
this.timeSinceLastAlive = 0;
|
||||
|
||||
if (!this.subscribed) {
|
||||
Messages.subscribe(COMMAND_CHANNEL);
|
||||
Messages.subscribe(SERVICE_CHANNEL);
|
||||
var localThis = this;
|
||||
Messages.messageReceived.connect(function (channel, message, senderID) {
|
||||
if (channel == SERVICE_CHANNEL) {
|
||||
localThis._processServiceMessage(message, senderID);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
// ready to roll, enable
|
||||
this.subscribed = true;
|
||||
printDebug("Master Started");
|
||||
};
|
||||
|
||||
MasterController.prototype._processServiceMessage = function(message, senderID) {
|
||||
var service = unpackServiceMessage(message);
|
||||
if (service.dest == MASTER_ID) {
|
||||
if (service.command == AGENT_READY) {
|
||||
// check to see if we know about this agent
|
||||
var agentIndex = this.knownAgents.indexOf(service.src);
|
||||
if (agentIndex < 0) {
|
||||
this._onAgentAvailableForHiring(service.src);
|
||||
} else {
|
||||
// Master think the agent is hired but not the other way around, forget about it
|
||||
printDebug("New agent still sending ready ? " + service.src + " " + agentIndex + " Forgeting about it");
|
||||
// this._removeHiredAgent(agentIndex);
|
||||
}
|
||||
} else if (service.command == AGENT_ALIVE) {
|
||||
// check to see if we know about this agent
|
||||
var agentIndex = this.knownAgents.indexOf(service.src);
|
||||
if (agentIndex >= 0) {
|
||||
// yes so reset its alive beat
|
||||
this.hiredActors[agentIndex].alive();
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MasterController.prototype._onAgentAvailableForHiring = function(agentID) {
|
||||
if (this.hiringAgentsQueue.length == 0) {
|
||||
printDebug("No Actor on the hiring queue");
|
||||
return;
|
||||
}
|
||||
|
||||
printDebug("MasterController.prototype._onAgentAvailableForHiring " + agentID);
|
||||
var newActor = this.hiringAgentsQueue.pop();
|
||||
|
||||
var indexOfNewAgent = this.knownAgents.push(agentID);
|
||||
newActor.alive();
|
||||
newActor.agentID = agentID;
|
||||
this.hiredActors.push(newActor);
|
||||
|
||||
printDebug("New agent available to be hired " + agentID + " " + indexOfNewAgent);
|
||||
var serviceMessage = packServiceMessage(agentID, MASTER_HIRE_AGENT, MASTER_ID);
|
||||
printDebug("serviceMessage = " + serviceMessage);
|
||||
Messages.sendMessage(SERVICE_CHANNEL, serviceMessage);
|
||||
printDebug("message sent calling the actor" + JSON.stringify(newActor) );
|
||||
|
||||
newActor.onHired(newActor);
|
||||
}
|
||||
|
||||
MasterController.prototype.sendCommand = function(target, action, argument) {
|
||||
if (this.subscribed) {
|
||||
var command = packCommandMessage(target, action, argument);
|
||||
printDebug(command);
|
||||
Messages.sendMessage(COMMAND_CHANNEL, command);
|
||||
}
|
||||
};
|
||||
|
||||
MasterController.prototype.update = function(deltaTime) {
|
||||
this.timeSinceLastAlive += deltaTime;
|
||||
if (this.timeSinceLastAlive > ALIVE_PERIOD) {
|
||||
this.timeSinceLastAlive = 0;
|
||||
Messages.sendMessage(SERVICE_CHANNEL, packServiceMessage(BROADCAST_AGENTS, MASTER_ALIVE, MASTER_ID));
|
||||
|
||||
{
|
||||
// Check for alive connected agents
|
||||
var lostAgents = new Array();
|
||||
for (var i = 0; i < this.hiredActors.length; i++) {
|
||||
var actor = this.hiredActors[i];
|
||||
var lastAlive = actor.incrementAliveCycle()
|
||||
if (lastAlive > NUM_CYCLES_BEFORE_RESET) {
|
||||
printDebug("Agent Lost, firing Agent #" + i + " ID " + actor.agentID);
|
||||
lostAgents.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
// now fire gathered lost agents from end to begin
|
||||
while (lostAgents.length > 0) {
|
||||
printDebug("Firing " + lostAgents.length + " agents" + JSON.stringify(lostAgents));
|
||||
this.fireAgent(this.hiredActors[lostAgents.pop()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MasterController.prototype.hireAgent = function(actor) {
|
||||
if (actor == null) {
|
||||
printDebug("trying to hire an agent with a null actor, abort");
|
||||
return;
|
||||
}
|
||||
if (actor.isConnected()) {
|
||||
printDebug("trying to hire an agent already connected, abort");
|
||||
return;
|
||||
}
|
||||
this.hiringAgentsQueue.unshift(actor);
|
||||
};
|
||||
|
||||
MasterController.prototype.fireAgent = function(actor) {
|
||||
// check to see if we know about this agent
|
||||
printDebug("MasterController.prototype.fireAgent" + actor.agentID);
|
||||
|
||||
// Try the waiting list first
|
||||
var waitingIndex = this.hiringAgentsQueue.indexOf(actor);
|
||||
if (waitingIndex >= 0) {
|
||||
printDebug("fireAgent found actor on waiting queue #" + waitingIndex);
|
||||
var lostActor = this.hiringAgentsQueue.splice(waitingIndex, 1);
|
||||
if (lostActor.length) {
|
||||
lostActor[0].onFired(lostActor[0]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// then the hired agents
|
||||
var actorIndex = this.knownAgents.indexOf(actor.agentID);
|
||||
if (actorIndex >= 0) {
|
||||
printDebug("fired actor found #" + actorIndex);
|
||||
this._removeHiredAgent(actorIndex);
|
||||
}
|
||||
}
|
||||
|
||||
MasterController.prototype._removeHiredAgent = function(actorIndex) {
|
||||
// check to see if we know about this agent
|
||||
if (actorIndex >= 0) {
|
||||
printDebug("MasterController.prototype._removeHiredAgent #" + this.knownAgents[actorIndex])
|
||||
this.knownAgents.splice(actorIndex, 1);
|
||||
|
||||
var lostActor = this.hiredActors[actorIndex];
|
||||
this.hiredActors.splice(actorIndex, 1);
|
||||
|
||||
var lostAgentID = lostActor.agentID;
|
||||
lostActor.agentID = INVALID_AGENT;
|
||||
|
||||
if (lostAgentID != INVALID_AGENT) {
|
||||
printDebug("fired actor is still connected, send fire command");
|
||||
Messages.sendMessage(SERVICE_CHANNEL, packServiceMessage(lostAgentID, MASTER_FIRE_AGENT, MASTER_ID));
|
||||
}
|
||||
|
||||
lostActor.onFired(lostActor);
|
||||
}
|
||||
}
|
||||
|
||||
this.MasterController = MasterController;
|
||||
|
||||
// agent side
|
||||
//---------------------------------
|
||||
var AgentController = function() {
|
||||
this.subscribed = false;
|
||||
this._init();
|
||||
|
||||
this.onHired = function() {};
|
||||
this.onCommand = function(command) {};
|
||||
this.onFired = function() {};
|
||||
};
|
||||
|
||||
AgentController.prototype._init = function() {
|
||||
this.isHired= false;
|
||||
this.timeSinceLastAlive = 0;
|
||||
this.numCyclesWithoutAlive = 0;
|
||||
this.agentUUID = makeUniqueUUID(Agent.sessionUUID);
|
||||
printDebug("this.agentUUID = " + this.agentUUID);
|
||||
}
|
||||
|
||||
AgentController.prototype.destroy = function() {
|
||||
if (this.subscribed) {
|
||||
this.fired();
|
||||
Messages.unsubscribe(SERVICE_CHANNEL);
|
||||
Messages.unsubscribe(COMMAND_CHANNEL);
|
||||
this.subscribed = true;
|
||||
}
|
||||
};
|
||||
|
||||
AgentController.prototype.reset = function() {
|
||||
// If already hired, fire
|
||||
this.fired();
|
||||
|
||||
if (!this.subscribed) {
|
||||
Messages.subscribe(COMMAND_CHANNEL);
|
||||
Messages.subscribe(SERVICE_CHANNEL);
|
||||
var localThis = this;
|
||||
Messages.messageReceived.connect(function (channel, message, senderID) {
|
||||
if (channel == SERVICE_CHANNEL) {
|
||||
localThis._processServiceMessage(message, senderID);
|
||||
return;
|
||||
}
|
||||
if (channel == COMMAND_CHANNEL) {
|
||||
localThis._processCommandMessage(message, senderID);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.subscribed = true;
|
||||
printDebug("Client Started");
|
||||
};
|
||||
|
||||
AgentController.prototype._processServiceMessage = function(message, senderID) {
|
||||
var service = unpackServiceMessage(message);
|
||||
printDebug("Client " + this.agentUUID + " Received message = " + message);
|
||||
if (service.dest == this.agentUUID) {
|
||||
if (service.command != AGENT_READY) {
|
||||
|
||||
// this is potentially a message to hire me if i m not already
|
||||
if (!this.isHired && (service.command == MASTER_HIRE_AGENT)) {
|
||||
printDebug(service.command);
|
||||
this.isHired = true;
|
||||
printDebug("Client Hired by master UUID" + service.src);
|
||||
this.onHired();
|
||||
this.alive();
|
||||
return;
|
||||
}
|
||||
|
||||
// Or maybe a message to fire me if i m not hired
|
||||
if (this.isHired && (service.command == MASTER_FIRE_AGENT)) {
|
||||
printDebug("Client Fired by master UUID" + senderID);
|
||||
this.fired();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ((service.src == MASTER_ID) && (service.command == MASTER_ALIVE)) {
|
||||
this.numCyclesWithoutAlive = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AgentController.prototype._processCommandMessage = function(message, senderID) {
|
||||
// ONly work if hired
|
||||
if (this.isHired) {
|
||||
var command = unpackCommandMessage(message);
|
||||
if ((command.dest_key == this.agentUUID) || (command.dest_key == BROADCAST_AGENTS)) {
|
||||
printDebug("Command received = " + JSON.stringify(command) + senderID);
|
||||
this.onCommand(command);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
AgentController.prototype.update = function(deltaTime) {
|
||||
this.timeSinceLastAlive += deltaTime;
|
||||
if (this.timeSinceLastAlive > ALIVE_PERIOD) {
|
||||
if (this.subscribed) {
|
||||
if (!this.isHired) {
|
||||
Messages.sendMessage(SERVICE_CHANNEL, packServiceMessage(MASTER_ID, AGENT_READY, this.agentUUID));
|
||||
//printDebug("Client Ready" + SERVICE_CHANNEL + AGENT_READY);
|
||||
} else {
|
||||
// Send alive beat
|
||||
printDebug("beat !");
|
||||
Messages.sendMessage(SERVICE_CHANNEL, packServiceMessage(MASTER_ID, AGENT_ALIVE, this.agentUUID));
|
||||
|
||||
// Listen for master beat
|
||||
this.numCyclesWithoutAlive++;
|
||||
if (this.numCyclesWithoutAlive > NUM_CYCLES_BEFORE_RESET) {
|
||||
printDebug("Master Lost, self firing Agent");
|
||||
this.fired();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.timeSinceLastAlive = 0;
|
||||
}
|
||||
};
|
||||
|
||||
AgentController.prototype.fired = function() {
|
||||
// clear the state first
|
||||
var wasHired = this.isHired;
|
||||
|
||||
// reset
|
||||
this._init();
|
||||
|
||||
// then custom fire if was hired
|
||||
if (wasHired) {
|
||||
this.onFired();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.AgentController = AgentController;
|
||||
|
||||
|
||||
|
||||
this.BROADCAST_AGENTS = BROADCAST_AGENTS;
|
||||
})();
|
||||
|
||||
|
||||
|
|
@ -9,18 +9,15 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
Script.include("./AgentPoolController.js");
|
||||
var agentController = new AgentController();
|
||||
|
||||
// Set the following variables to the values needed
|
||||
var commandChannel = "com.highfidelity.PlaybackChannel1";
|
||||
var clip_url = null;
|
||||
var playFromCurrentLocation = true;
|
||||
var useDisplayName = true;
|
||||
var useAttachments = true;
|
||||
var useAvatarModel = true;
|
||||
|
||||
// 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
|
||||
|
||||
// Set position/orientation/scale here if playFromCurrentLocation is true
|
||||
Avatar.position = { x:0, y: 0, z: 0 };
|
||||
|
@ -28,16 +25,12 @@ Avatar.orientation = Quat.fromPitchYawRollDegrees(0, 0, 0);
|
|||
Avatar.scale = 1.0;
|
||||
|
||||
var totalTime = 0;
|
||||
var subscribed = false;
|
||||
var WAIT_FOR_AUDIO_MIXER = 1;
|
||||
|
||||
// Script. DO NOT MODIFY BEYOND THIS LINE.
|
||||
var DO_NOTHING = 0;
|
||||
var PLAY = 1;
|
||||
var PLAY_LOOP = 2;
|
||||
var STOP = 3;
|
||||
var SHOW = 4;
|
||||
var HIDE = 5;
|
||||
var LOAD = 6;
|
||||
|
||||
Recording.setPlayFromCurrentLocation(playFromCurrentLocation);
|
||||
|
@ -46,29 +39,15 @@ Recording.setPlayerUseAttachments(useAttachments);
|
|||
Recording.setPlayerUseHeadModel(false);
|
||||
Recording.setPlayerUseSkeletonModel(useAvatarModel);
|
||||
|
||||
function getAction(channel, message, senderID) {
|
||||
if(subscribed) {
|
||||
var command = JSON.parse(message);
|
||||
print("I'm the agent " + id + " and I received this: ID: " + command.id_key + " Action: " + command.action_key + " URL: " + command.clip_url_key);
|
||||
|
||||
if (command.id_key == id || command.id_key == -1) {
|
||||
if (command.action_key === 6) {
|
||||
clip_url = command.clip_url_key;
|
||||
}
|
||||
|
||||
action = command.action_key;
|
||||
print("That command was for me!");
|
||||
print("My clip is: " + clip_url);
|
||||
} else {
|
||||
action = DO_NOTHING;
|
||||
}
|
||||
|
||||
switch(action) {
|
||||
function agentCommand(command) {
|
||||
if(true) {
|
||||
|
||||
// var command = JSON.parse(message);
|
||||
print("I'm the agent " + this.agentUUID + " and I received this: Dest: " + command.dest_key + " Action: " + command.action_key + " URL: " + command.argument_key);
|
||||
|
||||
switch(command.action_key) {
|
||||
case PLAY:
|
||||
print("Play");
|
||||
if (!Agent.isAvatar) {
|
||||
Agent.isAvatar = true;
|
||||
}
|
||||
if (!Recording.isPlaying()) {
|
||||
Recording.startPlaying();
|
||||
}
|
||||
|
@ -76,9 +55,6 @@ function getAction(channel, message, senderID) {
|
|||
break;
|
||||
case PLAY_LOOP:
|
||||
print("Play loop");
|
||||
if (!Agent.isAvatar) {
|
||||
Agent.isAvatar = true;
|
||||
}
|
||||
if (!Recording.isPlaying()) {
|
||||
Recording.startPlaying();
|
||||
}
|
||||
|
@ -90,75 +66,60 @@ function getAction(channel, message, senderID) {
|
|||
Recording.stopPlaying();
|
||||
}
|
||||
break;
|
||||
case SHOW:
|
||||
print("Show");
|
||||
if (!Agent.isAvatar) {
|
||||
Agent.isAvatar = true;
|
||||
}
|
||||
break;
|
||||
case HIDE:
|
||||
print("Hide");
|
||||
if (Recording.isPlaying()) {
|
||||
Recording.stopPlaying();
|
||||
}
|
||||
Agent.isAvatar = false;
|
||||
break;
|
||||
case LOAD:
|
||||
print("Load");
|
||||
if(clip_url !== null) {
|
||||
Recording.loadRecording(clip_url);
|
||||
}
|
||||
break;
|
||||
case DO_NOTHING:
|
||||
{
|
||||
print("Load" + command.argument_key);
|
||||
print("Agent #" + command.dest_key + " loading clip URL: " + command.argument_key);
|
||||
Recording.loadRecording(command.argument_key);
|
||||
print("After Load" + command.argument_key);
|
||||
Recording.setPlayerTime(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
print("Unknown action: " + action);
|
||||
print("Unknown action: " + command.action_key);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (Recording.isPlaying()) {
|
||||
Recording.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function agentHired() {
|
||||
print("Agent Hired from playbackAgents.js");
|
||||
Agent.isAvatar = true;
|
||||
Recording.stopPlaying();
|
||||
Recording.setPlayerLoop(false);
|
||||
Recording.setPlayerTime(0);
|
||||
}
|
||||
|
||||
function agentFired() {
|
||||
print("Agent Fired from playbackAgents.js");
|
||||
Recording.stopPlaying();
|
||||
Recording.setPlayerTime(0);
|
||||
Recording.setPlayerLoop(false);
|
||||
Agent.isAvatar = false;
|
||||
}
|
||||
|
||||
|
||||
function update(deltaTime) {
|
||||
|
||||
totalTime += deltaTime;
|
||||
|
||||
if (totalTime > WAIT_FOR_AUDIO_MIXER) {
|
||||
if (!subscribed) {
|
||||
Messages.subscribe(commandChannel); // command channel
|
||||
Messages.subscribe(announceIDChannel); // id announce channel
|
||||
subscribed = true;
|
||||
print("I'm the agent and I am ready to receive!");
|
||||
}
|
||||
if (subscribed && id == UNKNOWN_AGENT_ID) {
|
||||
print("sending ready, id:" + id);
|
||||
Messages.sendMessage(announceIDChannel, "ready");
|
||||
if (!agentController.subscribed) {
|
||||
agentController.reset();
|
||||
agentController.onCommand = agentCommand;
|
||||
agentController.onHired = agentHired;
|
||||
agentController.onFired = agentFired;
|
||||
}
|
||||
}
|
||||
|
||||
agentController.update(deltaTime);
|
||||
}
|
||||
|
||||
|
||||
function scriptEnding() {
|
||||
|
||||
agentController.destroy();
|
||||
}
|
||||
|
||||
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
|
||||
if (id == UNKNOWN_AGENT_ID) {
|
||||
var parts = message.split(".");
|
||||
var agentID = parts[0];
|
||||
var agentIndex = parts[1];
|
||||
if (agentID == Agent.sessionUUID) {
|
||||
id = agentIndex;
|
||||
Messages.unsubscribe(announceIDChannel); // id announce channel
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channel == commandChannel) {
|
||||
getAction(channel, message, senderID);
|
||||
}
|
||||
});
|
||||
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
|
@ -8,31 +8,24 @@
|
|||
// 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("./AgentPoolController.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 channel = "com.highfidelity.PlaybackChannel1";
|
||||
var subscribed = false;
|
||||
var clip_url = null;
|
||||
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";
|
||||
|
||||
// Script. DO NOT MODIFY BEYOND THIS LINE.
|
||||
Script.include("../libraries/toolBars.js");
|
||||
//Script.include("../libraries/toolBars.js");
|
||||
Script.include(HIFI_PUBLIC_BUCKET + "scripts/libraries/toolBars.js");
|
||||
// We want small icons
|
||||
Tool.IMAGE_HEIGHT /= 2;
|
||||
Tool.IMAGE_WIDTH /= 2;
|
||||
|
||||
var DO_NOTHING = 0;
|
||||
var PLAY = 1;
|
||||
var PLAY_LOOP = 2;
|
||||
var STOP = 3;
|
||||
var SHOW = 4;
|
||||
var HIDE = 5;
|
||||
var LOAD = 6;
|
||||
|
||||
var windowDimensions = Controller.getViewportDimensions();
|
||||
|
@ -44,241 +37,381 @@ var COLOR_MASTER = { red: 0, green: 0, blue: 0 };
|
|||
var TEXT_HEIGHT = 12;
|
||||
var TEXT_MARGIN = 3;
|
||||
|
||||
var toolBars = new Array();
|
||||
var nameOverlays = new Array();
|
||||
var onOffIcon = new Array();
|
||||
var playIcon = new Array();
|
||||
var playLoopIcon = new Array();
|
||||
var stopIcon = new Array();
|
||||
var loadIcon = new Array();
|
||||
|
||||
setupPlayback();
|
||||
|
||||
function setupPlayback() {
|
||||
ac_number = Window.prompt("Insert number of agents: ","1");
|
||||
if (ac_number === "" || ac_number === null) {
|
||||
ac_number = 1;
|
||||
}
|
||||
Messages.subscribe(channel);
|
||||
subscribed = true;
|
||||
setupToolBars();
|
||||
// Add new features to Actor class:
|
||||
Actor.prototype.destroy = function() {
|
||||
print("Actor.prototype.destroy");
|
||||
print("Need to fire myself" + this.agentID);
|
||||
masterController.fireAgent(this);
|
||||
}
|
||||
|
||||
function setupToolBars() {
|
||||
if (toolBars.length > 0) {
|
||||
print("Multiple calls to Recorder.js:setupToolBars()");
|
||||
return;
|
||||
}
|
||||
Tool.IMAGE_HEIGHT /= 2;
|
||||
Tool.IMAGE_WIDTH /= 2;
|
||||
|
||||
for (i = 0; i <= ac_number; i++) {
|
||||
toolBars.push(new ToolBar(0, 0, ToolBar.HORIZONTAL));
|
||||
toolBars[i].setBack((i == ac_number) ? COLOR_MASTER : COLOR_TOOL_BAR, ALPHA_OFF);
|
||||
|
||||
onOffIcon.push(toolBars[i].addTool({
|
||||
imageURL: TOOL_ICON_URL + "ac-on-off.svg",
|
||||
subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||
x: 0, y: 0,
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_ON,
|
||||
visible: true
|
||||
}, true, true));
|
||||
|
||||
playIcon[i] = toolBars[i].addTool({
|
||||
imageURL: TOOL_ICON_URL + "play.svg",
|
||||
subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
var playLoopWidthFactor = 1.65;
|
||||
playLoopIcon[i] = toolBars[i].addTool({
|
||||
imageURL: TOOL_ICON_URL + "play-and-loop.svg",
|
||||
subImage: { x: 0, y: 0, width: playLoopWidthFactor * Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||
width: playLoopWidthFactor * Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
stopIcon[i] = toolBars[i].addTool({
|
||||
imageURL: TOOL_ICON_URL + "recording-stop.svg",
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
loadIcon[i] = toolBars[i].addTool({
|
||||
imageURL: TOOL_ICON_URL + "recording-upload.svg",
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
nameOverlays.push(Overlays.addOverlay("text", {
|
||||
backgroundColor: { red: 0, green: 0, blue: 0 },
|
||||
font: { size: TEXT_HEIGHT },
|
||||
text: (i == ac_number) ? "Master" : i + ". " +
|
||||
((i < names.length) ? names[i] :
|
||||
"AC" + i),
|
||||
x: 0, y: 0,
|
||||
width: toolBars[i].width + ToolBar.SPACING,
|
||||
height: TEXT_HEIGHT + TEXT_MARGIN,
|
||||
leftMargin: TEXT_MARGIN,
|
||||
topMargin: TEXT_MARGIN,
|
||||
alpha: ALPHA_OFF,
|
||||
backgroundAlpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}));
|
||||
|
||||
Actor.prototype.resetClip = function(clipURL, onLoadClip) {
|
||||
this.clipURL = clipURL;
|
||||
this.onLoadClip = onLoadClip;
|
||||
if (this.isConnected()) {
|
||||
this.onLoadClip(this);
|
||||
}
|
||||
}
|
||||
|
||||
function sendCommand(id, action) {
|
||||
if (action === SHOW) {
|
||||
toolBars[id].selectTool(onOffIcon[id], false);
|
||||
toolBars[id].setAlpha(ALPHA_ON, playIcon[id]);
|
||||
toolBars[id].setAlpha(ALPHA_ON, playLoopIcon[id]);
|
||||
toolBars[id].setAlpha(ALPHA_ON, stopIcon[id]);
|
||||
toolBars[id].setAlpha(ALPHA_ON, loadIcon[id]);
|
||||
} else if (action === HIDE) {
|
||||
toolBars[id].selectTool(onOffIcon[id], true);
|
||||
toolBars[id].setAlpha(ALPHA_OFF, playIcon[id]);
|
||||
toolBars[id].setAlpha(ALPHA_OFF, playLoopIcon[id]);
|
||||
toolBars[id].setAlpha(ALPHA_OFF, stopIcon[id]);
|
||||
toolBars[id].setAlpha(ALPHA_OFF, loadIcon[id]);
|
||||
} else if (toolBars[id].toolSelected(onOffIcon[id])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == (toolBars.length - 1)) {
|
||||
id = -1; // Master command becomes broadcast.
|
||||
}
|
||||
|
||||
var message = {
|
||||
id_key: id,
|
||||
action_key: action,
|
||||
clip_url_key: clip_url
|
||||
};
|
||||
|
||||
if(subscribed){
|
||||
Messages.sendMessage(channel, JSON.stringify(message));
|
||||
print("Message sent!");
|
||||
clip_url = null;
|
||||
|
||||
Actor.prototype.onMousePressEvent = function(clickedOverlay) {
|
||||
if (this.playIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
||||
masterController.sendCommand(this.agentID, PLAY);
|
||||
} else if (this.playLoopIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
||||
masterController.sendCommand(this.agentID, PLAY_LOOP);
|
||||
} else if (this.stopIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
||||
masterController.sendCommand(this.agentID, STOP);
|
||||
} else if (this.nameOverlay === clickedOverlay) {
|
||||
print("Actor: " + JSON.stringify(this));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function mousePressEvent(event) {
|
||||
clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y });
|
||||
Actor.prototype._buildUI = function() {
|
||||
print("Actor.prototype._buildUI = " + JSON.stringify(this));
|
||||
|
||||
// Check master control
|
||||
var i = toolBars.length - 1;
|
||||
if (onOffIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
if (toolBars[i].toolSelected(onOffIcon[i])) {
|
||||
sendCommand(i, SHOW);
|
||||
} else {
|
||||
sendCommand(i, HIDE);
|
||||
}
|
||||
} else if (playIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
sendCommand(i, PLAY);
|
||||
} else if (playLoopIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
sendCommand(i, PLAY_LOOP);
|
||||
} else if (stopIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
sendCommand(i, STOP);
|
||||
} else if (loadIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
this.toolbar = new ToolBar(0, 0, ToolBar.HORIZONTAL);
|
||||
|
||||
this.toolbar.setBack(COLOR_TOOL_BAR, ALPHA_OFF);
|
||||
|
||||
this.playIcon = this.toolbar.addTool({
|
||||
imageURL: TOOL_ICON_URL + "play.svg",
|
||||
subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
var playLoopWidthFthis = 1.65;
|
||||
this.playLoopIcon = this.toolbar.addTool({
|
||||
imageURL: TOOL_ICON_URL + "play-and-loop.svg",
|
||||
subImage: { x: 0, y: 0, width: playLoopWidthFthis * Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||
width: playLoopWidthFthis * Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
this.stopIcon = this.toolbar.addTool({
|
||||
imageURL: TOOL_ICON_URL + "recording-stop.svg",
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
this.nameOverlay = Overlays.addOverlay("text", {
|
||||
backgroundColor: { red: 0, green: 0, blue: 0 },
|
||||
font: { size: TEXT_HEIGHT },
|
||||
text: "AC offline",
|
||||
x: 0, y: 0,
|
||||
width: this.toolbar.width + ToolBar.SPACING,
|
||||
height: TEXT_HEIGHT + TEXT_MARGIN,
|
||||
leftMargin: TEXT_MARGIN,
|
||||
topMargin: TEXT_MARGIN,
|
||||
alpha: ALPHA_OFF,
|
||||
backgroundAlpha: ALPHA_OFF,
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
|
||||
Actor.prototype._destroyUI = function() {
|
||||
this.toolbar.cleanup();
|
||||
Overlays.deleteOverlay(this.nameOverlay);
|
||||
}
|
||||
|
||||
Actor.prototype.moveUI = function(pos) {
|
||||
var textSize = TEXT_HEIGHT + 2 * TEXT_MARGIN;
|
||||
this.toolbar.move(pos.x, pos.y);
|
||||
|
||||
Overlays.editOverlay(this.nameOverlay, {
|
||||
x: this.toolbar.x - ToolBar.SPACING,
|
||||
y: this.toolbar.y - textSize
|
||||
});
|
||||
}
|
||||
|
||||
Director = function() {
|
||||
this.actors = new Array();
|
||||
this.toolbar = null;
|
||||
this._buildUI();
|
||||
this.requestPerformanceLoad = false;
|
||||
this.performanceURL = "";
|
||||
};
|
||||
|
||||
Director.prototype.destroy = function () {
|
||||
print("Director.prototype.destroy")
|
||||
this.clearActors();
|
||||
this.toolbar.cleanup();
|
||||
Overlays.deleteOverlay(this.nameOverlay);
|
||||
}
|
||||
|
||||
Director.prototype.clearActors = function () {
|
||||
print("Director.prototype.clearActors")
|
||||
while (this.actors.length > 0) {
|
||||
this.actors.pop().destroy();
|
||||
}
|
||||
|
||||
this.actors = new Array();// Brand new actors
|
||||
}
|
||||
|
||||
Director.prototype._buildUI = function () {
|
||||
this.toolbar = new ToolBar(0, 0, ToolBar.HORIZONTAL);
|
||||
|
||||
this.toolbar.setBack(COLOR_MASTER, ALPHA_OFF);
|
||||
|
||||
this.onOffIcon = this.toolbar.addTool({
|
||||
imageURL: TOOL_ICON_URL + "ac-on-off.svg",
|
||||
subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||
x: 0, y: 0,
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_ON,
|
||||
visible: true
|
||||
}, true, true);
|
||||
|
||||
this.playIcon = this.toolbar.addTool({
|
||||
imageURL: TOOL_ICON_URL + "play.svg",
|
||||
subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
var playLoopWidthFthis = 1.65;
|
||||
this.playLoopIcon = this.toolbar.addTool({
|
||||
imageURL: TOOL_ICON_URL + "play-and-loop.svg",
|
||||
subImage: { x: 0, y: 0, width: playLoopWidthFthis * Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||
width: playLoopWidthFthis * Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
this.stopIcon = this.toolbar.addTool({
|
||||
imageURL: TOOL_ICON_URL + "recording-stop.svg",
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
this.loadIcon = this.toolbar.addTool({
|
||||
imageURL: TOOL_ICON_URL + "recording-upload.svg",
|
||||
width: Tool.IMAGE_WIDTH,
|
||||
height: Tool.IMAGE_HEIGHT,
|
||||
alpha: ALPHA_OFF,
|
||||
visible: true
|
||||
}, false);
|
||||
|
||||
this.nameOverlay = Overlays.addOverlay("text", {
|
||||
backgroundColor: { red: 0, green: 0, blue: 0 },
|
||||
font: { size: TEXT_HEIGHT },
|
||||
text: "Master",
|
||||
x: 0, y: 0,
|
||||
width: this.toolbar.width + ToolBar.SPACING,
|
||||
height: TEXT_HEIGHT + TEXT_MARGIN,
|
||||
leftMargin: TEXT_MARGIN,
|
||||
topMargin: TEXT_MARGIN,
|
||||
alpha: ALPHA_OFF,
|
||||
backgroundAlpha: ALPHA_OFF,
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
|
||||
Director.prototype.onMousePressEvent = function(clickedOverlay) {
|
||||
if (this.playIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
||||
print("master play");
|
||||
masterController.sendCommand(BROADCAST_AGENTS, PLAY);
|
||||
} else if (this.onOffIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
||||
this.clearActors();
|
||||
return true;
|
||||
} else if (this.playLoopIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
||||
masterController.sendCommand(BROADCAST_AGENTS, PLAY_LOOP);
|
||||
} else if (this.stopIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
||||
masterController.sendCommand(BROADCAST_AGENTS, STOP);
|
||||
} else if (this.loadIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
||||
input_text = Window.prompt("Insert the url of the clip: ","");
|
||||
if (!(input_text === "" || input_text === null)) {
|
||||
clip_url = input_text;
|
||||
sendCommand(i, LOAD);
|
||||
}
|
||||
print("Performance file ready to be loaded url = " + input_text);
|
||||
this.requestPerformanceLoad = true;
|
||||
this.performanceURL = input_text;
|
||||
}
|
||||
} else if (this.nameOverlay === clickedOverlay) {
|
||||
print("Director: " + JSON.stringify(this));
|
||||
} else {
|
||||
// Check individual controls
|
||||
for (i = 0; i < ac_number; i++) {
|
||||
if (onOffIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
if (toolBars[i].toolSelected(onOffIcon[i], false)) {
|
||||
sendCommand(i, SHOW);
|
||||
} else {
|
||||
sendCommand(i, HIDE);
|
||||
}
|
||||
} else if (playIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
sendCommand(i, PLAY);
|
||||
} else if (playLoopIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
sendCommand(i, PLAY_LOOP);
|
||||
} else if (stopIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
sendCommand(i, STOP);
|
||||
} else if (loadIcon[i] === toolBars[i].clicked(clickedOverlay, false)) {
|
||||
input_text = Window.prompt("Insert the url of the clip: ","");
|
||||
if (!(input_text === "" || input_text === null)) {
|
||||
clip_url = input_text;
|
||||
sendCommand(i, LOAD);
|
||||
}
|
||||
} else {
|
||||
|
||||
for (var i = 0; i < this.actors.length; i++) {
|
||||
if (this.actors[i].onMousePressEvent(clickedOverlay)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false; // nothing clicked from our known overlays
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Director.prototype.moveUI = function(pos) {
|
||||
var textSize = TEXT_HEIGHT + 2 * TEXT_MARGIN;
|
||||
var relative = { x: pos.x, y: pos.y + (this.actors.length + 1) * (Tool.IMAGE_HEIGHT + ToolBar.SPACING + textSize) };
|
||||
|
||||
this.toolbar.move(relative.x, windowDimensions.y - relative.y);
|
||||
Overlays.editOverlay(this.nameOverlay, {
|
||||
x: this.toolbar.x - ToolBar.SPACING,
|
||||
y: this.toolbar.y - textSize
|
||||
});
|
||||
|
||||
for (var i = 0; i < this.actors.length; i++) {
|
||||
this.actors[i].moveUI({x: relative.x, y: windowDimensions.y - relative.y +
|
||||
(i + 1) * (Tool.IMAGE_HEIGHT + ToolBar.SPACING + textSize)});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Director.prototype.reloadPerformance = function() {
|
||||
this.requestPerformanceLoad = false;
|
||||
|
||||
if (this.performanceURL[0] == '{') {
|
||||
var jsonPerformance = JSON.parse(this.performanceURL);
|
||||
this.onPerformanceLoaded(jsonPerformance);
|
||||
} else {
|
||||
|
||||
var urlpartition = this.performanceURL.split(".");
|
||||
print(urlpartition[0]);
|
||||
print(urlpartition[1]);
|
||||
|
||||
if ((urlpartition.length > 1) && (urlpartition[urlpartition.length - 1] === "hfr")) {
|
||||
print("detected a unique clip url");
|
||||
var oneClipPerformance = new Object();
|
||||
oneClipPerformance.avatarClips = new Array();
|
||||
oneClipPerformance.avatarClips[0] = input_text;
|
||||
|
||||
print(JSON.stringify(oneClipPerformance));
|
||||
|
||||
// we make a local simple performance file with a single clip and pipe in directly
|
||||
this.onPerformanceLoaded(oneClipPerformance);
|
||||
return true;
|
||||
} else {
|
||||
// FIXME: I cannot pass directly this.onPerformanceLoaded, is that exepected ?
|
||||
var localThis = this;
|
||||
Assets.downloadData(input_text, function(data) { localThis.onPerformanceLoaded(JSON.parse(data)); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Director.prototype.onPerformanceLoaded = function(performanceJSON) {
|
||||
// First fire all the current actors
|
||||
this.clearActors();
|
||||
|
||||
print("Director.prototype.onPerformanceLoaded = " + JSON.stringify(performanceJSON));
|
||||
if (performanceJSON.avatarClips != null) {
|
||||
var numClips = performanceJSON.avatarClips.length;
|
||||
print("Found " + numClips + "in the performance file, and currently using " + this.actors.length + " actor(s)");
|
||||
|
||||
for (var i = 0; i < numClips; i++) {
|
||||
this.hireActor(performanceJSON.avatarClips[i]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Director.prototype.hireActor = function(clipURL) {
|
||||
print("new actor = " + this.actors.length );
|
||||
var newActor = new Actor();
|
||||
newActor.clipURL = null;
|
||||
newActor.onLoadClip = function(clip) {};
|
||||
|
||||
var localThis = this;
|
||||
newActor.onHired = function(actor) {
|
||||
print("agent hired from Director! " + actor.agentID)
|
||||
Overlays.editOverlay(actor.nameOverlay, {
|
||||
text: "AC " + actor.agentID,
|
||||
backgroundColor: { red: 0, green: 255, blue: 0 }
|
||||
});
|
||||
|
||||
if (actor.clipURL != null) {
|
||||
print("agent hired, calling load clip for url " + actor.clipURL);
|
||||
actor.onLoadClip(actor);
|
||||
}
|
||||
};
|
||||
|
||||
newActor.onFired = function(actor) {
|
||||
print("agent fired from playbackMaster! " + actor.agentID);
|
||||
var index = localThis.actors.indexOf(actor);
|
||||
if (index >= 0) {
|
||||
localThis.actors.splice(index, 1);
|
||||
}
|
||||
|
||||
actor._destroyUI();
|
||||
|
||||
actor.destroy();
|
||||
moveUI();
|
||||
}
|
||||
|
||||
newActor.resetClip(clipURL, function(actor) {
|
||||
print("Load clip for agent" + actor.agentID + " calling load clip for url " + actor.clipURL);
|
||||
masterController.sendCommand(actor.agentID, LOAD, actor.clipURL);
|
||||
});
|
||||
|
||||
|
||||
masterController.hireAgent(newActor);
|
||||
newActor._buildUI();
|
||||
|
||||
this.actors.push(newActor);
|
||||
|
||||
moveUI();
|
||||
}
|
||||
|
||||
|
||||
masterController.reset();
|
||||
var director = new Director();
|
||||
|
||||
moveUI();
|
||||
|
||||
|
||||
function mousePressEvent(event) {
|
||||
print("mousePressEvent");
|
||||
clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y });
|
||||
|
||||
// Check director and actors
|
||||
director.onMousePressEvent(clickedOverlay);
|
||||
}
|
||||
|
||||
function moveUI() {
|
||||
var textSize = TEXT_HEIGHT + 2 * TEXT_MARGIN;
|
||||
var relative = { x: 70, y: 75 + (ac_number) * (Tool.IMAGE_HEIGHT + ToolBar.SPACING + textSize) };
|
||||
|
||||
for (i = 0; i <= ac_number; i++) {
|
||||
toolBars[i].move(relative.x,
|
||||
windowDimensions.y - relative.y +
|
||||
i * (Tool.IMAGE_HEIGHT + ToolBar.SPACING + textSize));
|
||||
|
||||
Overlays.editOverlay(nameOverlays[i], {
|
||||
x: toolBars[i].x - ToolBar.SPACING,
|
||||
y: toolBars[i].y - textSize
|
||||
});
|
||||
}
|
||||
director.moveUI({ x: 70, y: 75});
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
function update(deltaTime) {
|
||||
var newDimensions = Controller.getViewportDimensions();
|
||||
if (windowDimensions.x != newDimensions.x ||
|
||||
windowDimensions.y != newDimensions.y) {
|
||||
windowDimensions = newDimensions;
|
||||
moveUI();
|
||||
}
|
||||
|
||||
if (director.requestPerformanceLoad) {
|
||||
print("reloadPerformance " + director.performanceURL);
|
||||
director.reloadPerformance();
|
||||
}
|
||||
|
||||
masterController.update(deltaTime);
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
for (i = 0; i <= ac_number; i++) {
|
||||
toolBars[i].cleanup();
|
||||
Overlays.deleteOverlay(nameOverlays[i]);
|
||||
}
|
||||
|
||||
if (subscribed) {
|
||||
Messages.unsubscribe(channel);
|
||||
}
|
||||
Messages.unsubscribe(announceIDChannel);
|
||||
print("cleanup")
|
||||
director.destroy();
|
||||
masterController.destroy();
|
||||
}
|
||||
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
||||
|
||||
|
||||
Messages.subscribe(announceIDChannel);
|
||||
Messages.messageReceived.connect(function (channel, message, senderID) {
|
||||
if (channel == announceIDChannel && message == "ready") {
|
||||
// check to see if we know about this agent
|
||||
if (knownAgents.indexOf(senderID) < 0) {
|
||||
var indexOfNewAgent = knownAgents.length;
|
||||
knownAgents[indexOfNewAgent] = senderID;
|
||||
var acknowledgeMessage = senderID + "." + indexOfNewAgent;
|
||||
Messages.sendMessage(announceIDChannel, acknowledgeMessage);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
moveUI();
|
Loading…
Reference in a new issue