From 5d9915243ba1a93934969e7e203a25c6f4c9f9d1 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 12 Feb 2019 14:44:37 -0800 Subject: SL-10406, SL-10464: Remove experience injections and destroy push environment when finished. --- indra/newview/llenvironment.cpp | 233 ++++++++++++++++++++++++++++------------ indra/newview/llenvironment.h | 2 +- 2 files changed, 165 insertions(+), 70 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 1018075409..25983e245b 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -380,7 +380,7 @@ namespace } } - void removeInjection(const std::string keyname, LLUUID experience) + void removeInjection(const std::string keyname, LLUUID experience, LLSettingsBase::Seconds transition) { auto it = mInjections.begin(); while (it != mInjections.end()) @@ -388,6 +388,11 @@ namespace if ((keyname.empty() || ((*it)->mKeyName == keyname)) && (experience.isNull() || (experience == (*it)->mExperience))) { + if (transition != LLEnvironment::TRANSITION_INSTANT) + { + typename Injection::ptr_t injection = std::make_shared(transition, keyname, (*it)->mLastValue, false, LLUUID::null); + mInjections.push_front(injection); // push them in at the front so we don't check them again. + } mInjections.erase(it++); } else @@ -398,17 +403,23 @@ namespace { if (experience.isNull() || ((*itexp).second == experience)) { + if (transition != LLEnvironment::TRANSITION_INSTANT) + { + typename Injection::ptr_t injection = std::make_shared(transition, (*itexp).first, mOverrideValues[(*itexp).first], false, LLUUID::null); + mInjections.push_front(injection); + } mOverrideValues.erase((*itexp).first); mOverrideExps.erase(itexp++); } else ++itexp; } + std::stable_sort(mInjections.begin(), mInjections.end(), [](const typename Injection::ptr_t &a, const typename Injection::ptr_t &b) { return a->mTimeRemaining < b->mTimeRemaining; }); } - void removeInjections(LLUUID experience_id) + void removeInjections(LLUUID experience_id, LLSettingsBase::Seconds transition) { - removeInjection(std::string(), experience_id); + removeInjection(std::string(), experience_id, transition); } void injectExperienceValues(LLSD values, LLUUID experience_id, typename LLSettingsBase::Seconds transition) @@ -452,7 +463,7 @@ namespace { if ((*it)->mBlendIn) { - LL_WARNS("LAPRAS") << "Done blending '" << key_name << "' after " << (*it)->mTransition.value() - (*it)->mTimeRemaining.value() << " value now=" << target << LL_ENDL; + //_WARNS("LAPRAS") << "Done blending '" << key_name << "' after " << (*it)->mTransition.value() - (*it)->mTimeRemaining.value() << " value now=" << target << LL_ENDL; mOverrideValues[key_name] = target; mOverrideExps[key_name] = (*it)->mExperience; this->mSettings[key_name] = target; @@ -468,7 +479,10 @@ namespace } else if (skips.find(key_name) == skips.end()) { - this->mSettings[key_name] = this->interpolateSDValue(key_name, value, target, this->getParameterMap(), mix, slerps); + if (!(*it)->mBlendIn) + mix = 1.0 - mix; + (*it)->mLastValue = this->interpolateSDValue(key_name, value, target, this->getParameterMap(), mix, slerps); + this->mSettings[key_name] = (*it)->mLastValue; } } @@ -490,6 +504,11 @@ namespace } + bool hasInjections() const + { + return (!mInjections.empty() || (mOverrideValues.size() > 0)); + } + protected: struct Injection { @@ -508,6 +527,7 @@ namespace typename LLSettingsBase::Seconds mTimeRemaining; std::string mKeyName; LLSD mValue; + LLSD mLastValue; LLUUID mExperience; S32 mIndex; bool mBlendIn; @@ -662,7 +682,6 @@ namespace { setBlendFactor(mix); } - } typedef LLSettingsInjected LLSettingsInjectedSky; @@ -688,30 +707,30 @@ namespace void injectSkySettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition); void injectWaterSettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition); - void clearInjections(LLUUID experience_id); - -// virtual void setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset) override; -// virtual void setSky(const LLSettingsSky::ptr_t &psky) override; -// virtual void setWater(const LLSettingsWater::ptr_t &pwater) override; + void clearInjections(LLUUID experience_id, LLSettingsBase::Seconds transition_time); virtual void animate() override; LLEnvironment::DayInstance::ptr_t getBaseDayInstance() const { return mBaseDayInstance; } void setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday); - S32 experiencesActive() const { return mActiveExperiences.size(); } + S32 countExperiencesActive() const { return mActiveExperiences.size(); } bool isOverriddenSky() const { return !mSkyExperience.isNull(); } bool isOverriddenWater() const { return !mWaterExperience.isNull(); } + + bool hasInjections() const; private: void animateSkyChange(LLSettingsSky::ptr_t psky, LLSettingsBase::Seconds transition); void animateWaterChange(LLSettingsWater::ptr_t pwater, LLSettingsBase::Seconds transition); void onEnvironmentChanged(LLEnvironment::EnvSelection_t env); + void onParcelChange(); void checkExperience(); + LLEnvironment::DayInstance::ptr_t mBaseDayInstance; LLSettingsInjectedSky::ptr_t mInjectedSky; @@ -721,6 +740,7 @@ namespace LLUUID mSkyExperience; LLUUID mWaterExperience; LLEnvironment::connection_t mEnvChangeConnection; + boost::signals2::connection mParcelChangeConnection; }; class InjectedTransition : public LLEnvironment::DayTransition @@ -949,6 +969,7 @@ bool LLEnvironment::isInventoryEnabled() const void LLEnvironment::onRegionChange() { + // TODO: Use test experiences rather than full clear. clearExperienceEnvironment(LLUUID::null, TRANSITION_DEFAULT); LLViewerRegion* cur_region = gAgent.getRegion(); @@ -1438,8 +1459,12 @@ void LLEnvironment::update(const LLViewerCamera * cam) F32Seconds delta(timer.getElapsedTimeAndResetF32()); - mCurrentEnvironment->applyTimeDelta(delta); + { + DayInstance::ptr_t keeper = mCurrentEnvironment; + // make sure the current environment does not go away until applyTimeDelta is done. + mCurrentEnvironment->applyTimeDelta(delta); + } // update clouds, sun, and general updateCloudScroll(); @@ -2254,7 +2279,7 @@ void LLEnvironment::handleEnvironmentPush(LLSD &message) void LLEnvironment::handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition) { - clearExperienceEnvironment(experience_id, transition); + clearExperienceEnvironment(experience_id, LLSettingsBase::Seconds(transition)); } void LLEnvironment::handleEnvironmentPushFull(LLUUID experience_id, LLSD &message, F32 transition) @@ -2274,12 +2299,14 @@ void LLEnvironment::handleEnvironmentPushPartial(LLUUID experience_id, LLSD &mes setExperienceEnvironment(experience_id, settings, LLSettingsBase::Seconds(transition)); } -void LLEnvironment::clearExperienceEnvironment(LLUUID experience_id, F32 transition_time) +void LLEnvironment::clearExperienceEnvironment(LLUUID experience_id, LLSettingsBase::Seconds transition_time) { - if (hasEnvironment(ENV_PUSH)) + DayInjection::ptr_t injection = std::dynamic_pointer_cast(getEnvironmentInstance(ENV_PUSH)); + if (injection) { - clearEnvironment(ENV_PUSH); - updateEnvironment(LLSettingsBase::Seconds(transition_time)); + injection->clearInjections(experience_id, transition_time); +// clearEnvironment(ENV_PUSH); +// updateEnvironment(transition_time); } } @@ -2297,10 +2324,6 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLUUID asset_ [this, experience_id, transition_time](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onSetExperienceEnvAssetLoaded(experience_id, settings, transition_time, status); -// // individual settings will be overridden by the settings. No need to keep injections. -// onSetEnvAssetLoaded(ENV_PUSH, asset_id, settings, -// LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, -// LLSettingsBase::Seconds(transition_time), status, NO_VERSION); }); @@ -2350,7 +2373,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F3 if (sky.isUndefined() && water.isUndefined()) { - clearExperienceEnvironment(experience_id, transition_time); + clearExperienceEnvironment(experience_id, LLSettingsBase::Seconds(transition_time)); return; } @@ -2708,20 +2731,25 @@ namespace mDayExperience(), mSkyExperience(), mWaterExperience(), - mEnvChangeConnection() + mEnvChangeConnection(), + mParcelChangeConnection() { mInjectedSky = std::make_shared(LLEnvironment::instance().getCurrentSky()); mInjectedWater = std::make_shared(LLEnvironment::instance().getCurrentWater()); mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance(); mSky = mInjectedSky; mWater = mInjectedWater; + mEnvChangeConnection = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env, S32) { onEnvironmentChanged(env); }); + mParcelChangeConnection = gAgent.addParcelChangedCallback([this]() { onParcelChange(); }); } DayInjection::~DayInjection() { if (mEnvChangeConnection.connected()) mEnvChangeConnection.disconnect(); + if (mParcelChangeConnection.connected()) + mParcelChangeConnection.disconnect(); } @@ -2741,6 +2769,13 @@ namespace } mInjectedSky->update(); mInjectedWater->update(); + + if (!hasInjections()) + { // There are no injections being managed. This should really go away. + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); + } + return changed; } @@ -2754,6 +2789,13 @@ namespace mInjectedWater->setSource(mBaseDayInstance->getWater()); } + + bool DayInjection::hasInjections() const + { + return (!mSkyExperience.isNull() || !mWaterExperience.isNull() || !mDayExperience.isNull() || + mBlenderSky || mBlenderWater || mInjectedSky->hasInjections() || mInjectedWater->hasInjections()); + } + void DayInjection::setInjectedDay(const LLSettingsDay::ptr_t &pday, LLUUID experience_id, LLSettingsBase::Seconds transition) { mSkyExperience = experience_id; @@ -2795,55 +2837,107 @@ namespace mInjectedWater->injectExperienceValues(settings, experience_id, transition); } - void DayInjection::clearInjections(LLUUID experience_id) + void DayInjection::clearInjections(LLUUID experience_id, LLSettingsBase::Seconds transition_time) { - if (experience_id.isNull() || (experience_id == mSkyExperience)) - { + if ((experience_id.isNull() && !mDayExperience.isNull()) || (experience_id == mDayExperience)) + { + mDayExperience.setNull(); + if (mSkyExperience == experience_id) + mSkyExperience.setNull(); + if (mWaterExperience == experience_id) + mWaterExperience.setNull(); + + mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance(); + + if (mSkyExperience.isNull()) + animateSkyChange(mBaseDayInstance->getSky(), transition_time); + if (mWaterExperience.isNull()) + animateWaterChange(mBaseDayInstance->getWater(), transition_time); + } + + if ((experience_id.isNull() && !mSkyExperience.isNull()) || (experience_id == mSkyExperience)) + { mSkyExperience.setNull(); - mInjectedSky->setSource(mBaseDayInstance->getSky()); + animateSkyChange(mBaseDayInstance->getSky(), transition_time); } - mInjectedSky->removeInjections(experience_id); - if (experience_id.isNull() || (experience_id == mWaterExperience)) + if ((experience_id.isNull() && !mWaterExperience.isNull()) || (experience_id == mWaterExperience)) { mWaterExperience.setNull(); - mInjectedWater->setSource(mBaseDayInstance->getWater()); + animateWaterChange(mBaseDayInstance->getWater(), transition_time); } - mInjectedWater->removeInjections(experience_id); + + mInjectedSky->removeInjections(experience_id, transition_time); + mInjectedWater->removeInjections(experience_id, transition_time); if (experience_id.isNull()) mActiveExperiences.clear(); else mActiveExperiences.erase(experience_id); + + if ((transition_time == LLEnvironment::TRANSITION_INSTANT) && (countExperiencesActive() == 0)) + { // Only do this if instant and there are no other experiences injecting values. + // (otherwise will be handled after transition) + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); + } } void DayInjection::animateSkyChange(LLSettingsSky::ptr_t psky, LLSettingsBase::Seconds transition) { - LLSettingsSky::ptr_t start_sky(mInjectedSky->getSource()->buildClone()); - LLSettingsSky::ptr_t target_sky(start_sky->buildClone()); - mInjectedSky->setSource(target_sky); + if (transition == LLEnvironment::TRANSITION_INSTANT) + { + mBlenderSky.reset(); + mInjectedSky->setSource(psky); + } + else + { + LLSettingsSky::ptr_t start_sky(mInjectedSky->getSource()->buildClone()); + LLSettingsSky::ptr_t target_sky(start_sky->buildClone()); + mInjectedSky->setSource(target_sky); - mBlenderSky = std::make_shared(target_sky, start_sky, psky, transition); - mBlenderSky->setOnFinished( - [this, psky](LLSettingsBlender::ptr_t blender) { - mBlenderSky.reset(); - mInjectedSky->setSource(psky); - setSky(mInjectedSky); - }); + mBlenderSky = std::make_shared(target_sky, start_sky, psky, transition); + mBlenderSky->setOnFinished( + [this, psky](LLSettingsBlender::ptr_t blender) + { + mBlenderSky.reset(); + mInjectedSky->setSource(psky); + setSky(mInjectedSky); + if (!mBlenderWater && (countExperiencesActive() == 0)) + { + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); + } + }); + } } void DayInjection::animateWaterChange(LLSettingsWater::ptr_t pwater, LLSettingsBase::Seconds transition) { - LLSettingsWater::ptr_t start_Water(mInjectedWater->getSource()->buildClone()); - LLSettingsWater::ptr_t scratch_Water(start_Water->buildClone()); - mInjectedWater->setSource(scratch_Water); - - mBlenderWater = std::make_shared(scratch_Water, start_Water, pwater, transition); - mBlenderWater->setOnFinished( - [this, pwater](LLSettingsBlender::ptr_t blender) { + if (transition == LLEnvironment::TRANSITION_INSTANT) + { mBlenderWater.reset(); mInjectedWater->setSource(pwater); - setWater(mInjectedWater); - }); + } + else + { + LLSettingsWater::ptr_t start_Water(mInjectedWater->getSource()->buildClone()); + LLSettingsWater::ptr_t scratch_Water(start_Water->buildClone()); + mInjectedWater->setSource(scratch_Water); + + mBlenderWater = std::make_shared(scratch_Water, start_Water, pwater, transition); + mBlenderWater->setOnFinished( + [this, pwater](LLSettingsBlender::ptr_t blender) + { + mBlenderWater.reset(); + mInjectedWater->setSource(pwater); + setWater(mInjectedWater); + if (!mBlenderSky && (countExperiencesActive() == 0)) + { + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); + } + }); + } } void DayInjection::onEnvironmentChanged(LLEnvironment::EnvSelection_t env) @@ -2869,6 +2963,23 @@ namespace } } + void DayInjection::onParcelChange() + { + S32 parcel_id(INVALID_PARCEL_ID); + LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel(); + + if (!parcel) + return; + + parcel_id = parcel->getLocalID(); + + // TODO: + // 1) Get the parcel experiences, + // 2) check against injected experiences + // 3) if not allowed remove them. + + } + void DayInjection::checkExperience() { if ((!mDayExperience.isNull()) && (mSkyExperience != mDayExperience) && (mWaterExperience != mDayExperience)) @@ -2886,22 +2997,6 @@ namespace } - -// void DayInjection::setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset) -// { -// -// } -// -// void DayInjection::setSky(const LLSettingsSky::ptr_t &psky) -// { -// -// } -// -// void DayInjection::setWater(const LLSettingsWater::ptr_t &pwater) -// { -// -// } - void InjectedTransition::animate() { mNextInstance->animate(); @@ -2936,8 +3031,8 @@ namespace if (!mBlenderSky && !mBlenderWater) mInjection->setBaseDayInstance(mNextInstance); -// else -// mInjection->mInjectedWater->setSource(mNextInstance->getWater()); + else + mInjection->mInjectedWater->setSource(mNextInstance->getWater()); }); } else diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 1798c6dd61..6a930959bb 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -410,7 +410,7 @@ private: void handleEnvironmentPushFull(LLUUID experience_id, LLSD &message, F32 transition); void handleEnvironmentPushPartial(LLUUID experience_id, LLSD &message, F32 transition); - void clearExperienceEnvironment(LLUUID experience_id, F32 transition_time); + void clearExperienceEnvironment(LLUUID experience_id, LLSettingsBase::Seconds transition_time); void setExperienceEnvironment(LLUUID experience_id, LLUUID asset_id, F32 transition_time); void setExperienceEnvironment(LLUUID experience_id, LLSD environment, F32 transition_time); void onSetExperienceEnvAssetLoaded(LLUUID experience_id, LLSettingsBase::ptr_t setting, F32 transition_time, S32 status); -- cgit v1.2.3