[BUG-234493] Add "Until key release" to the gesture "Wait"

master
Kyler Eastridge 2023-10-07 16:54:30 -04:00 committed by Andrey Lihatskiy
parent 0f742298de
commit 02ca44eea5
8 changed files with 126 additions and 9 deletions

View File

@ -68,6 +68,8 @@ void LLMultiGesture::reset()
mCurrentStep = 0;
mWaitTimer.reset();
mWaitingTimer = FALSE;
mTriggeredByKey = FALSE;
mKeyReleased = FALSE;
mWaitingAnimations = FALSE;
mWaitingAtEnd = FALSE;
mRequestedAnimIDs.clear();

View File

@ -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
{

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -154,6 +154,7 @@ private:
LLComboBox* mAnimationCombo;
LLComboBox* mSoundCombo;
LLLineEditor* mChatEditor;
LLCheckBoxCtrl* mWaitKeyReleaseCheck;
LLCheckBoxCtrl* mWaitAnimCheck;
LLCheckBoxCtrl* mWaitTimeCheck;
LLLineEditor* mWaitTimeEditor;

View File

@ -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()

View File

@ -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"
@ -294,6 +294,15 @@
top_pad="3"
width="80" />
</radio_group>
<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"
@ -301,7 +310,7 @@
layout="topleft"
left="28"
name="wait_anim_check"
top="330"
top_delta="20"
width="100" />
<check_box
follows="top|left"