Auto-play recording at start-up

This commit is contained in:
David Rowe 2017-04-09 15:52:56 +12:00
parent adabcab888
commit d60d4d0755

View file

@ -36,14 +36,16 @@
TIMESTAMP_UPDATE_INTERVAL = 2000, // TODO: Final value. TIMESTAMP_UPDATE_INTERVAL = 2000, // TODO: Final value.
ENTITY_NAME = "Recording", ENTITY_NAME = "Recording",
ENTITY_DESCRIPTION = "Avatar recording to play back", ENTITY_DESCRIPTION = "Avatar recording to play back",
ENTITIY_POSITION = { x: -16382, y: -16382, z: -16382 }; // Near but not right on corner boundary. ENTITIY_POSITION = { x: -16382, y: -16382, z: -16382 }, // Near but not right on domain corner.
ENTITY_SEARCH_DELTA = { x: 1, y: 1, z: 1 }; // Allow for position imprecision.
function onUpdateTimestamp() { function onUpdateTimestamp() {
userData.timestamp = Date.now(); userData.timestamp = Date.now();
Entities.editEntity(entityID, { userData: JSON.stringify(userData) }); Entities.editEntity(entityID, { userData: JSON.stringify(userData) });
EntityViewer.queryOctree(); // Keep up to date ready for find().
} }
function create(filename, scriptUUID) { function create(filename, position, orientation, scriptUUID) {
// Create a new persistence entity (even if already have one but that should never occur). // Create a new persistence entity (even if already have one but that should never occur).
var properties; var properties;
@ -53,6 +55,8 @@
userData = { userData = {
recording: filename, recording: filename,
position: position,
orientation: orientation,
scriptUUID: scriptUUID, scriptUUID: scriptUUID,
timestamp: Date.now() timestamp: Date.now()
}; };
@ -67,12 +71,48 @@
}; };
entityID = Entities.addEntity(properties); entityID = Entities.addEntity(properties);
// TODO: Handle failure adding entity?
updateTimestampTimer = Script.setInterval(onUpdateTimestamp, TIMESTAMP_UPDATE_INTERVAL); updateTimestampTimer = Script.setInterval(onUpdateTimestamp, TIMESTAMP_UPDATE_INTERVAL);
} }
function find() { function find(scriptUUID) {
// TODO // Find a recording that isn't being played.
var isFound = false,
entityIDs,
index = 0,
properties;
entityIDs = Entities.findEntities(ENTITIY_POSITION, ENTITY_SEARCH_DELTA.x);
if (entityIDs.length > 0) {
while (!isFound && index < entityIDs.length - 1) {
// Find recording that isn't being played.
index += 1;
properties = Entities.getEntityProperties(entityIDs[index], ["name", "userData"]);
if (properties.name === ENTITY_NAME) {
// TODO: Guard against userData being non-existent or corrupt.
userData = JSON.parse(properties.userData);
// TODO: Verify that 2 * TIMESTAMP_UPDATE_INTERVAL is sufficient w.r.t. EntityViewer.queryOctree().
isFound = (Date.now() - userData.timestamp) > (2 * TIMESTAMP_UPDATE_INTERVAL);
}
}
}
if (isFound) {
// Claim recording.
// TODO: Guard against another AC script claiming the same recording at the same time.
entityID = entityIDs[index];
userData.scriptUUID = scriptUUID;
userData.timestamp = Date.now();
Entities.editEntity(entityID, { userData: JSON.stringify(userData) });
updateTimestampTimer = Script.setInterval(onUpdateTimestamp, TIMESTAMP_UPDATE_INTERVAL);
// Return recording info to play.
return { recording: userData.recording, position: userData.position, orientation: userData.orientation };
}
EntityViewer.queryOctree(); // Update octree ready for next find() call.
return null;
} }
function destroy() { function destroy() {
@ -86,32 +126,41 @@
} }
} }
function setUp() {
// Set up EntityViewer so that can do Entities.findEntities().
// Position and orientation set so that viewing entities only in corner of domain.
var entityViewerPosition = Vec3.sum(ENTITIY_POSITION, ENTITY_SEARCH_DELTA);
EntityViewer.setPosition(entityViewerPosition);
EntityViewer.setOrientation(Quat.lookAtSimple(entityViewerPosition, ENTITIY_POSITION));
EntityViewer.queryOctree();
}
function tearDown() {
// Nothing to do.
}
return { return {
create: create, create: create,
find: find, find: find,
destroy: destroy destroy: destroy,
setUp: setUp,
tearDown: tearDown
}; };
}()); }());
Player = (function () { Player = (function () {
// Recording playback functions. // Recording playback functions.
var isPlayingRecording = false, var isPlayingRecording = false,
recordingFilename = ""; recordingFilename = "",
autoPlayTimer = null,
function play(recording, position, orientation) { AUTOPLAY_SEARCH_INTERVAL = 2000; // TODO: Final value.
isPlayingRecording = true;
recordingFilename = recording;
log("Play new recording " + recordingFilename);
Entity.create(recordingFilename, scriptUUID);
function playRecording(recording, position, orientation) {
Agent.isAvatar = true; Agent.isAvatar = true;
Avatar.position = position; Avatar.position = position;
Avatar.orientation = orientation; Avatar.orientation = orientation;
Recording.loadRecording(recordingFilename); Recording.loadRecording(recording);
Recording.setPlayFromCurrentLocation(true); Recording.setPlayFromCurrentLocation(true);
Recording.setPlayerUseDisplayName(true); Recording.setPlayerUseDisplayName(true);
Recording.setPlayerUseHeadModel(false); Recording.setPlayerUseHeadModel(false);
@ -123,8 +172,30 @@
Recording.startPlaying(); Recording.startPlaying();
} }
function play(recording, position, orientation) {
isPlayingRecording = true;
recordingFilename = recording;
log("Play new recording " + recordingFilename);
Entity.create(recordingFilename, position, orientation, scriptUUID);
playRecording(recordingFilename, position, orientation);
}
function autoPlay() { function autoPlay() {
// TODO: Automatically play a persisted recording, if any. var recording;
recording = Entity.find(scriptUUID);
if (recording) {
isPlayingRecording = true;
recordingFilename = recording.recording;
log("Play persisted recording " + recordingFilename);
playRecording(recording.recording, recording.position, recording.orientation);
} else {
autoPlayTimer = Script.setTimeout(autoPlay, AUTOPLAY_SEARCH_INTERVAL); // Try again soon.
}
} }
function stop() { function stop() {
@ -148,11 +219,15 @@
} }
function setUp() { function setUp() {
// Nothing to do. Entity.setUp();
} }
function tearDown() { function tearDown() {
// Nothing to do. if (autoPlayTimer) {
Script.clearTimeout(autoPlayTimer);
autoPlayTimer = null;
}
Entity.tearDown();
} }
return { return {
@ -174,7 +249,7 @@
heartbeatTimer = Script.setTimeout(sendHeartbeat, HEARTBEAT_INTERVAL); heartbeatTimer = Script.setTimeout(sendHeartbeat, HEARTBEAT_INTERVAL);
} }
function cancelHeartbeat() { function stopHeartbeat() {
if (heartbeatTimer) { if (heartbeatTimer) {
Script.clearTimeout(heartbeatTimer); Script.clearTimeout(heartbeatTimer);
heartbeatTimer = null; heartbeatTimer = null;
@ -195,7 +270,7 @@
break; break;
case PLAYER_COMMAND_STOP: case PLAYER_COMMAND_STOP:
Player.stop(); Player.stop();
Player.autoPlay(); Player.autoPlay(); // There may be another recording to play.
sendHeartbeat(); sendHeartbeat();
break; break;
} }
@ -215,12 +290,12 @@
} }
function tearDown() { function tearDown() {
cancelHeartbeat(); stopHeartbeat();
Player.stop();
Messages.messageReceived.disconnect(onMessageReceived); Messages.messageReceived.disconnect(onMessageReceived);
Messages.unsubscribe(HIFI_PLAYER_CHANNEL); Messages.unsubscribe(HIFI_PLAYER_CHANNEL);
Player.stop();
Player.tearDown(); Player.tearDown();
} }