summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcharacter/llmultigesture.cpp2
-rw-r--r--indra/llcharacter/llmultigesture.h10
-rw-r--r--indra/newview/llgesturemgr.cpp76
-rw-r--r--indra/newview/llgesturemgr.h11
-rw-r--r--indra/newview/llpreviewgesture.cpp11
-rw-r--r--indra/newview/llpreviewgesture.h1
-rw-r--r--indra/newview/llviewerwindow.cpp9
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_gesture.xml15
8 files changed, 126 insertions, 9 deletions
diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp
index 7ed242f90a..511d931569 100644
--- a/indra/llcharacter/llmultigesture.cpp
+++ b/indra/llcharacter/llmultigesture.cpp
@@ -68,6 +68,8 @@ void LLMultiGesture::reset()
mCurrentStep = 0;
mWaitTimer.reset();
mWaitingTimer = FALSE;
+ mTriggeredByKey = FALSE;
+ mKeyReleased = FALSE;
mWaitingAnimations = FALSE;
mWaitingAtEnd = FALSE;
mRequestedAnimIDs.clear();
diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h
index 92820159d4..1865ec089c 100644
--- a/indra/llcharacter/llmultigesture.h
+++ b/indra/llcharacter/llmultigesture.h
@@ -83,9 +83,18 @@ public:
// We're waiting for triggered animations to stop playing
BOOL mWaitingAnimations;
+ // We're waiting for key release
+ BOOL mWaitingKeyRelease;
+
// We're waiting a fixed amount of time
BOOL mWaitingTimer;
+ // We're waiting for triggered animations to stop playing
+ BOOL mTriggeredByKey;
+
+ // Has the key been released?
+ BOOL mKeyReleased;
+
// Waiting after the last step played for all animations to complete
BOOL mWaitingAtEnd;
@@ -210,6 +219,7 @@ public:
const U32 WAIT_FLAG_TIME = 0x01;
const U32 WAIT_FLAG_ALL_ANIM = 0x02;
+const U32 WAIT_FLAG_KEY_RELEASE = 0x04;
class LLGestureStepWait : public LLGestureStep
{
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index c0f773968d..ce00bf3a54 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -58,6 +58,9 @@
// Longest time, in seconds, to wait for all animations to stop playing
const F32 MAX_WAIT_ANIM_SECS = 30.f;
+// Longest time, in seconds, to wait for a key release.
+// This should be relatively long, but not too long. 10 minutes is enough
+const F32 MAX_WAIT_KEY_SECS = 60.f * 10.f;
// Lightweight constructor.
// init() does the heavy lifting.
@@ -528,12 +531,13 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset
LLGestureMgr::instance().replaceGesture(base_item_id, gesture, new_asset_id);
}
-void LLGestureMgr::playGesture(LLMultiGesture* gesture)
+void LLGestureMgr::playGesture(LLMultiGesture* gesture, bool fromKeyPress)
{
if (!gesture) return;
// Reset gesture to first step
gesture->mCurrentStep = 0;
+ gesture->mTriggeredByKey = fromKeyPress;
// Add to list of playing
gesture->mPlaying = TRUE;
@@ -731,7 +735,8 @@ BOOL LLGestureMgr::triggerGesture(KEY key, MASK mask)
if (!gesture) continue;
if (gesture->mKey == key
- && gesture->mMask == mask)
+ && gesture->mMask == mask
+ && gesture->mWaitingKeyRelease == FALSE)
{
matching.push_back(gesture);
}
@@ -744,13 +749,38 @@ BOOL LLGestureMgr::triggerGesture(KEY key, MASK mask)
LLMultiGesture* gesture = matching[random];
- playGesture(gesture);
+ playGesture(gesture, TRUE);
return TRUE;
}
return FALSE;
}
+BOOL LLGestureMgr::triggerGestureRelease(KEY key, MASK mask)
+{
+ std::vector <LLMultiGesture *> matching;
+ item_map_t::iterator it;
+
+ // collect matching gestures
+ for (it = mActive.begin(); it != mActive.end(); ++it)
+ {
+ LLMultiGesture* gesture = (*it).second;
+
+ // asset data might not have arrived yet
+ if (!gesture) continue;
+
+ if (gesture->mKey == key
+ && gesture->mMask == mask)
+ {
+ gesture->mKeyReleased = TRUE;
+ }
+ }
+
+ //If we found one, block. Otherwise tell them it's free to go.
+ return matching.size() > 0;
+}
+
+
S32 LLGestureMgr::getPlayingCount() const
{
return mPlaying.size();
@@ -899,6 +929,33 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
continue;
}
+ // If we're waiting a fixed amount of time, check for timer
+ // expiration.
+ if (gesture->mWaitingKeyRelease)
+ {
+ // We're waiting for a certain amount of time to pass
+ LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
+ if (gesture->mKeyReleased)
+ {
+ // wait is done, continue execution
+ gesture->mWaitingKeyRelease = FALSE;
+ gesture->mCurrentStep++;
+ }
+ else if (gesture->mWaitTimer.getElapsedTimeF32() > MAX_WAIT_KEY_SECS)
+ {
+ LL_INFOS("GestureMgr") << "Waited too long for key release, continuing gesture."
+ << LL_ENDL;
+ gesture->mWaitingAnimations = FALSE;
+ gesture->mCurrentStep++;
+ }
+ else
+ {
+ // we're waiting, so execution is done for now
+ waiting = TRUE;
+ }
+ continue;
+ }
+
// If we're waiting on our animations to stop, poll for
// completion.
if (gesture->mWaitingAnimations)
@@ -1015,7 +1072,18 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
case STEP_WAIT:
{
LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
- if (wait_step->mFlags & WAIT_FLAG_TIME)
+ if (gesture->mTriggeredByKey // Only wait here IF we were triggered by a key!
+ && gesture->mKeyReleased == FALSE // We can only do this once! Prevent gestures infinitely running
+ && wait_step->mFlags & WAIT_FLAG_KEY_RELEASE)
+ {
+ // Lets wait for the key release first so we don't hold up re-presses
+
+ gesture->mWaitingKeyRelease = TRUE;
+ // Use the wait timer as a deadlock breaker for key release
+ // waits.
+ gesture->mWaitTimer.reset();
+ }
+ else if (wait_step->mFlags & WAIT_FLAG_TIME)
{
gesture->mWaitingTimer = TRUE;
gesture->mWaitTimer.reset();
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 7c8e8279c2..e805c91145 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -102,7 +102,10 @@ public:
const item_map_t& getActiveGestures() const { return mActive; }
// Force a gesture to be played, for example, if it is being
// previewed.
- void playGesture(LLMultiGesture* gesture);
+ void playGesture(LLMultiGesture* gesture, bool fromKeyPress);
+ void playGesture(LLMultiGesture* gesture) {
+ playGesture(gesture, FALSE);
+ }
void playGesture(const LLUUID& item_id);
// Stop all requested or playing anims for this gesture
@@ -118,10 +121,14 @@ public:
{
mCallbackMap[inv_item_id] = cb;
}
- // Trigger the first gesture that matches this key.
+ // Trigger a random gesture that matches this key.
// Returns TRUE if it finds a gesture bound to that key.
BOOL triggerGesture(KEY key, MASK mask);
+ // Trigger release wait on all gestures that matches this key.
+ // Returns TRUE if it finds a gesture bound to that key.
+ BOOL triggerGestureRelease(KEY key, MASK mask);
+
// Trigger all gestures referenced as substrings in this string
BOOL triggerAndReviseString(const std::string &str, std::string *revised_string = NULL);
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 759e7859f2..5d5010e27e 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -433,6 +433,11 @@ BOOL LLPreviewGesture::postBuild()
edit->setIgnoreTab(TRUE);
mChatEditor = edit;
+ check = getChild<LLCheckBoxCtrl>( "wait_key_release_check");
+ check->setVisible(FALSE);
+ check->setCommitCallback(onCommitWait, this);
+ mWaitKeyReleaseCheck = check;
+
check = getChild<LLCheckBoxCtrl>( "wait_anim_check");
check->setVisible(FALSE);
check->setCommitCallback(onCommitWait, this);
@@ -638,6 +643,7 @@ void LLPreviewGesture::refresh()
mAnimationRadio->setEnabled(FALSE);
mSoundCombo->setEnabled(FALSE);
mChatEditor->setEnabled(FALSE);
+ mWaitKeyReleaseCheck->setEnabled(FALSE);
mWaitAnimCheck->setEnabled(FALSE);
mWaitTimeCheck->setEnabled(FALSE);
mWaitTimeEditor->setEnabled(FALSE);
@@ -660,6 +666,7 @@ void LLPreviewGesture::refresh()
mAnimationRadio->setEnabled(modifiable);
mSoundCombo->setEnabled(modifiable);
mChatEditor->setEnabled(modifiable);
+ mWaitKeyReleaseCheck->setEnabled(modifiable);
mWaitAnimCheck->setEnabled(modifiable);
mWaitTimeCheck->setEnabled(modifiable);
mWaitTimeEditor->setEnabled(modifiable);
@@ -695,6 +702,7 @@ void LLPreviewGesture::refresh()
mAnimationRadio->setVisible(FALSE);
mSoundCombo->setVisible(FALSE);
mChatEditor->setVisible(FALSE);
+ mWaitKeyReleaseCheck->setVisible(FALSE);
mWaitAnimCheck->setVisible(FALSE);
mWaitTimeCheck->setVisible(FALSE);
mWaitTimeEditor->setVisible(FALSE);
@@ -739,6 +747,8 @@ void LLPreviewGesture::refresh()
{
LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
optionstext = getString("step_wait");
+ mWaitKeyReleaseCheck->setVisible(TRUE);
+ mWaitKeyReleaseCheck->set(wait_step->mFlags & WAIT_FLAG_KEY_RELEASE);
mWaitAnimCheck->setVisible(TRUE);
mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM);
mWaitTimeCheck->setVisible(TRUE);
@@ -1516,6 +1526,7 @@ void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data)
LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
U32 flags = 0x0;
+ if (self->mWaitKeyReleaseCheck->get()) flags |= WAIT_FLAG_KEY_RELEASE;
if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM;
if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME;
wait_step->mFlags = flags;
diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h
index f5c47d71b8..d0fddaf49a 100644
--- a/indra/newview/llpreviewgesture.h
+++ b/indra/newview/llpreviewgesture.h
@@ -154,6 +154,7 @@ private:
LLComboBox* mAnimationCombo;
LLComboBox* mSoundCombo;
LLLineEditor* mChatEditor;
+ LLCheckBoxCtrl* mWaitKeyReleaseCheck;
LLCheckBoxCtrl* mWaitAnimCheck;
LLCheckBoxCtrl* mWaitTimeCheck;
LLLineEditor* mWaitTimeEditor;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d68d0cd92c..8012a934c9 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2867,6 +2867,15 @@ BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
}
}
+ // Try for a new-format gesture
+ if (LLGestureMgr::instance().triggerGestureRelease(key, mask))
+ {
+ LL_DEBUGS() << "LLviewerWindow::handleKey new gesture release feature" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+ //Old format gestures do not support this, so no need to implement it.
+
// don't pass keys on to world when something in ui has focus
return gFocusMgr.childHasKeyboardFocus(mRootView)
|| LLMenuGL::getKeyboardMode()
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
index c4ac936334..28b735d297 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="460"
- min_height="460"
+ height="475"
+ min_height="475"
layout="topleft"
name="gesture_preview"
help_topic="gesture_preview"
@@ -297,11 +297,20 @@
<check_box
follows="top|left"
height="20"
+ label="until key is released"
+ layout="topleft"
+ left="28"
+ name="wait_key_release_check"
+ top="330"
+ width="100" />
+ <check_box
+ follows="top|left"
+ height="20"
label="until animations are done"
layout="topleft"
left="28"
name="wait_anim_check"
- top="330"
+ top_delta="20"
width="100" />
<check_box
follows="top|left"