initial new messaging - working but needs cleanup

This commit is contained in:
David Kelly 2017-03-13 18:33:36 -07:00
parent b65125157e
commit fa7283a6e2

View file

@ -29,16 +29,15 @@ const FRIENDING_SUCCESS_HAPTIC_STRENGTH = 1.0;
const HAPTIC_DURATION = 20; const HAPTIC_DURATION = 20;
var currentHand; var currentHand;
var isWaiting = false;
var nearbyAvatars = [];
var state = STATES.inactive; var state = STATES.inactive;
var waitingInterval;
var friendingInterval; var friendingInterval;
var entity; var entity;
var makingFriends = false; // really just for visualizations for now var makingFriends = false; // really just for visualizations for now
var animHandlerId; var animHandlerId;
var entityDimensionMultiplier = 1.0; var entityDimensionMultiplier = 1.0;
var friendingId; var friendingId;
var pendingFriendAckFrom;
var latestFriendRequestFrom;
function debug() { function debug() {
var stateString = "<" + STATE_STRINGS[state] + ">"; var stateString = "<" + STATE_STRINGS[state] + ">";
@ -126,24 +125,23 @@ function updateVisualization() {
} }
} }
function findNearbyAvatars(nearestOnly) {
// this should find the nearest avatars, returning an array of avatar, hand pairs. Currently
// looking at distance between hands.
function findNearbyAvatars() {
var nearbyAvatars = [];
var handPos = getHandPosition(MyAvatar, currentHand); var handPos = getHandPosition(MyAvatar, currentHand);
var minDistance = MAX_AVATAR_DISTANCE;
var nearbyAvatars = [];
AvatarList.getAvatarIdentifiers().forEach(function (identifier) { AvatarList.getAvatarIdentifiers().forEach(function (identifier) {
if (!identifier) { return; } if (!identifier) { return; }
var avatar = AvatarList.getAvatar(identifier); var avatar = AvatarList.getAvatar(identifier);
var distanceR = Vec3.distance(getHandPosition(avatar, Controller.Standard.RightHand), handPos); var distanceR = Vec3.distance(getHandPosition(avatar, Controller.Standard.RightHand), handPos);
var distanceL = Vec3.distance(getHandPosition(avatar, Controller.Standard.LeftHand), handPos); var distanceL = Vec3.distance(getHandPosition(avatar, Controller.Standard.LeftHand), handPos);
var distance = Math.min(distanceL, distanceR); var distance = Math.min(distanceL, distanceR);
if (distance < MAX_AVATAR_DISTANCE) { if (distance < minDistance) {
if (distance == distanceR) { if (nearestOnly) {
nearbyAvatars.push({avatar: identifier, hand: Controller.Standard.RightHand}); minDistance = distance;
} else { nearbyAvatars = [];
nearbyAvatars.push({avatar: identifier, hand: Controller.Standard.LeftHand});
} }
var hand = (distance == distanceR ? Controller.Standard.RightHand : Controller.Standard.LeftHand);
nearbyAvatars.push({avatar: identifier, hand: hand});
} }
}); });
return nearbyAvatars; return nearbyAvatars;
@ -156,24 +154,35 @@ function startHandshake(fromKeyboard) {
} }
debug("starting handshake for", currentHand); debug("starting handshake for", currentHand);
state = STATES.waiting; state = STATES.waiting;
friendingId = undefined;
entityDimensionMultiplier = 1.0; entityDimensionMultiplier = 1.0;
waitingInterval = Script.setInterval( pendingFriendAckFrom = undefined;
function () { // if we have a recent friendRequest, send an ack back
if (latestFriendRequestFrom) {
debug("sending friendAck to", latestFriendRequestFrom);
messageSend({
key: "friendAck",
id: latestFriendRequestFrom,
hand: handToString(currentHand)
});
} else {
var nearestAvatar = findNearbyAvatars(true)[0];
debug("nearest avatar", nearestAvatar);
if (nearestAvatar) {
pendingFriendAckFrom = nearestAvatar.avatar;
debug("sending friendRequest to", pendingFriendAckFrom);
messageSend({ messageSend({
key: "waiting", key: "friendRequest",
hand: handToString(currentHand) id: nearestAvatar.avatar,
hand: handToString(nearestAvatar.hand)
}); });
}, WAITING_INTERVAL); }
}
} }
function endHandshake() { function endHandshake() {
debug("ending handshake for", currentHand); debug("ending handshake for", currentHand);
currentHand = undefined; currentHand = undefined;
state = STATES.inactive; state = STATES.inactive;
if (waitingInterval) {
waitingInterval = Script.clearInterval(waitingInterval);
}
if (friendingInterval) { if (friendingInterval) {
friendingInterval = Script.clearInterval(friendingInterval); friendingInterval = Script.clearInterval(friendingInterval);
// send done to let friend know you are not making friends now // send done to let friend know you are not making friends now
@ -217,6 +226,7 @@ function messageSend(message) {
} }
function isNearby(id, hand) { function isNearby(id, hand) {
var nearbyAvatars = findNearbyAvatars();
for(var i = 0; i < nearbyAvatars.length; i++) { for(var i = 0; i < nearbyAvatars.length; i++) {
if (nearbyAvatars[i].avatar == id && handToString(nearbyAvatars[i].hand) == hand) { if (nearbyAvatars[i].avatar == id && handToString(nearbyAvatars[i].hand) == hand) {
return true; return true;
@ -246,20 +256,24 @@ function startFriending(id, hand) {
var count = 0; var count = 0;
debug("friending", id, "hand", hand); debug("friending", id, "hand", hand);
friendingId = id; friendingId = id;
pendingFriendAckFrom = undefined;
latestFriendRequestFrom = undefined;
state = STATES.friending; state = STATES.friending;
Controller.triggerHapticPulse(FRIENDING_HAPTIC_STRENGTH, HAPTIC_DURATION, handToHaptic(currentHand)); Controller.triggerHapticPulse(FRIENDING_HAPTIC_STRENGTH, HAPTIC_DURATION, handToHaptic(currentHand));
if (waitingInterval) {
waitingInterval = Script.clearInterval(waitingInterval); // send message that we are friending them
} messageSend({
key: "friending",
id: id,
hand: handToString(currentHand)
});
friendingInterval = Script.setInterval(function () { friendingInterval = Script.setInterval(function () {
nearbyAvatars = findNearbyAvatars();
entityDimensionMultiplier = 1.0 + 2.0 * ++count * FRIENDING_INTERVAL / FRIENDING_TIME; entityDimensionMultiplier = 1.0 + 2.0 * ++count * FRIENDING_INTERVAL / FRIENDING_TIME;
// insure senderID is still nearby
if (state != STATES.friending) { if (state != STATES.friending) {
debug("stopping friending interval, state changed"); debug("stopping friending interval, state changed");
friendingInterval = Script.clearInterval(friendingInterval); friendingInterval = Script.clearInterval(friendingInterval);
} } else if (!isNearby(id, hand)) {
if (!isNearby(id, hand)) {
// gotta go back to waiting // gotta go back to waiting
debug(id, "moved, back to waiting"); debug(id, "moved, back to waiting");
friendingInterval = Script.clearInterval(friendingInterval); friendingInterval = Script.clearInterval(friendingInterval);
@ -276,23 +290,21 @@ A simple sequence diagram:
Avatar A Avatar B Avatar A Avatar B
| | | |
| <---------(waiting) --- startHandshake | <-----(FriendRequest) -- startHandshake
startHandshake -- (waiting) -----> | startHandshake -- (FriendAck) ---> |
| | | |
| <-------(friending) -- startFriending | <-------(friending) -- startFriending
startFriending -- (friending) ---> | startFriending -- (friending) ---> |
| | | |
| friends | friends
friends | friends |
| ` | | <--------- (done) ---------- |
| ---------- (done) ---------> |
*/ */
function messageHandler(channel, messageString, senderID) { function messageHandler(channel, messageString, senderID) {
if (channel !== MESSAGE_CHANNEL) { if (channel !== MESSAGE_CHANNEL) {
return; return;
} }
if (state == STATES.inactive) {
return;
}
if (MyAvatar.sessionUUID === senderID) { // ignore my own if (MyAvatar.sessionUUID === senderID) { // ignore my own
return; return;
} }
@ -302,32 +314,42 @@ function messageHandler(channel, messageString, senderID) {
} catch (e) { } catch (e) {
debug(e); debug(e);
} }
debug("message", message);
switch (message.key) { switch (message.key) {
case "waiting": case "friendRequest":
if (state == STATES.inactive && message.id == MyAvatar.sessionUUID) {
debug("setting latestFriendRequestFrom", senderID);
latestFriendRequestFrom = senderID;
} else if (state == STATES.waiting && !pendingFriendAckFrom) {
// you are waiting for a friend request, so send the ack
pendingFriendAckFrom = senderID;
messageSend({
key: "friendAck",
id: senderID,
hand: handToString(currentHand)
});
}
// TODO: ponder keeping this up-to-date during
// other states?
break;
case "friendAck":
if (state == STATES.waiting && message.id == MyAvatar.sessionUUID) {
if (pendingFriendAckFrom && senderID != pendingFriendAckFrom) {
debug("ignoring friendAck from", senderID, ", waiting on", pendingFriendAckFrom);
break;
}
// start friending...
startFriending(senderID, message.hand);
}
break;
case "friending": case "friending":
if (state == STATES.waiting) { if (state == STATES.waiting && senderID == latestFriendRequestFrom) {
if (message.key == "friending" && message.id != MyAvatar.sessionUUID) { if (message.id != MyAvatar.sessionUUID) {
// for now, just ignore these. Hmm // for now, just ignore these. Hmm
debug("ignoring friending message", message, "from", senderID); debug("ignoring friending message", message, "from", senderID);
break; break;
} }
nearbyAvatars = findNearbyAvatars(); startFriending(senderID, message.hand);
if (isNearby(senderID, message.hand)) {
// if we are responding to a friending message (they didn't send a
// waiting before noticing us and friending), don't bother with sending
// a friending message?
messageSend({
key: "friending",
id: senderID,
hand: handToString(currentHand)
});
startFriending(senderID, message.hand);
} else {
// for now, ignore this. Hmm.
if (message.key == "friending") {
debug(senderID, "is friending us, but not close enough??");
}
}
} }
break; break;
case "done": case "done":
@ -343,6 +365,16 @@ function messageHandler(channel, messageString, senderID) {
// state anyways (if any) // state anyways (if any)
startHandshake(); startHandshake();
} }
} else {
// if waiting or inactive, lets clear the pending stuff
if (pendingFriendAckFrom == senderID || lastestFriendRequestFrom == senderID) {
if (state == STATES.inactive) {
pendingFriendAckFrom = undefined;
latestFriendRequestFrom = undefined;
} else {
startHandshake();
}
}
} }
break; break;
default: default: