diff options
-rw-r--r-- | indra/newview/llenvmanager.cpp | 95 | ||||
-rw-r--r-- | indra/newview/llenvmanager.h | 34 | ||||
-rw-r--r-- | indra/newview/llfloaterregioninfo.cpp | 361 | ||||
-rw-r--r-- | indra/newview/llfloaterregioninfo.h | 40 | ||||
-rw-r--r-- | indra/newview/llwldaycycle.cpp | 19 | ||||
-rw-r--r-- | indra/newview/llwldaycycle.h | 3 | ||||
-rw-r--r-- | indra/newview/llwlhandlers.cpp | 48 | ||||
-rw-r--r-- | indra/newview/llwlhandlers.h | 20 | ||||
-rw-r--r-- | indra/newview/llwlparammanager.cpp | 10 | ||||
-rw-r--r-- | indra/newview/llwlparammanager.h | 10 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_region_environment.xml | 7 |
11 files changed, 578 insertions, 69 deletions
diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp index 633b9c7c52..a08ca88459 100644 --- a/indra/newview/llenvmanager.cpp +++ b/indra/newview/llenvmanager.cpp @@ -367,7 +367,7 @@ void LLEnvManager::commitSettings(LLEnvKey::EScope scope) metadata["messageID"] = mLastReceivedID; // add last received update ID to outbound message so simulator can handle concurrent updates saveSettingsFromManagers(scope); // save current settings into settings store before grabbing from settings store and sending - success = LLEnvironmentApplyResponder::initiateRequest(makePacket(LLEnvKey::SCOPE_REGION, metadata)); + success = LLEnvironmentApply::initiateRequest(makePacket(LLEnvKey::SCOPE_REGION, metadata)); if(success) { // while waiting for the return message, render old settings @@ -484,7 +484,7 @@ void LLEnvManager::saveSettingsFromManagers(LLEnvKey::EScope scope) { // ensure only referenced region-scope skies are saved, resolve naming collisions, etc. std::map<LLWLParamKey, LLWLParamSet> final_references = LLWLParamManager::getInstance()->finalizeFromDayCycle(scope); - LLSD referenced_skies = LLWLParamManager::getInstance()->createSkyMap(final_references); + LLSD referenced_skies = LLWLParamManager::createSkyMap(final_references); LL_DEBUGS("Windlight Sync") << "Dumping referenced skies (" << final_references.size() << ") to LLSD: " << referenced_skies << LL_ENDL; @@ -764,6 +764,43 @@ void LLEnvManagerNew::dumpUserPrefs() LL_DEBUGS("Windlight") << "UseDayCycle: " << gSavedSettings.getBOOL("UseDayCycle") << LL_ENDL; } +// static +LLSD LLEnvManagerNew::getDayCycleByName(const std::string name) +{ + return LLWLDayCycle::loadCycleDataFromFile(name + ".xml"); +} + +void LLEnvManagerNew::requestRegionSettings() +{ + LLEnvironmentRequest::initiate(); +} + +bool LLEnvManagerNew::sendRegionSettings(const LLEnvironmentSettings& new_settings) +{ + LLSD metadata; + + metadata["regionID"] = gAgent.getRegion()->getRegionID(); + // add last received update ID to outbound message so simulator can handle concurrent updates + metadata["messageID"] = mLastReceivedID; + + return LLEnvironmentApply::initiateRequest(new_settings.makePacket(metadata)); +} + +boost::signals2::connection LLEnvManagerNew::setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb) +{ + return mRegionSettingsChangeSignal.connect(cb); +} + +boost::signals2::connection LLEnvManagerNew::setRegionChangeCallback(const region_change_signal_t::slot_type& cb) +{ + return mRegionChangeSignal.connect(cb); +} + +boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb) +{ + return mRegionSettingsAppliedSignal.connect(cb); +} + void LLEnvManagerNew::onRegionCrossing() { LL_DEBUGS("Windlight") << "Crossed region" << LL_ENDL; @@ -776,6 +813,34 @@ void LLEnvManagerNew::onTeleport() onRegionChange(false); } +void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content) +{ + // If the message was valid, grab the UUID from it and save it for next outbound update message. + mLastReceivedID = content[0]["messageID"].asUUID(); + + // Refresh cached region settings. + LL_DEBUGS("Windlight") << "Caching region environment settings: " << content << LL_ENDL; + F32 sun_hour = 0; // *TODO + LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour); + mCachedRegionPrefs = new_settings; + + // If using server settings, update managers. + // This also adds server skies to the WL param mgr. + updateManagersFromPrefs(mInterpNextChangeMessage); + + // Let interested parties know about the region settings update. + mRegionSettingsChangeSignal(); + + // reset + mInterpNextChangeMessage = false; +} + +void LLEnvManagerNew::onRegionSettingsApplyResponse(bool ok) +{ + LL_DEBUGS("Windlight") << "Applying region settings " << (ok ? "succeeded" : "failed") << LL_ENDL; + mRegionSettingsAppliedSignal(ok); +} + //-- private methods ---------------------------------------------------------- // virtual @@ -795,12 +860,6 @@ void LLEnvManagerNew::updateManagersFromPrefs(bool interpolate) LLWLParamManager::instance().applyUserPrefs(interpolate); } -void LLEnvManagerNew::sendRegionSettingsRequest() -{ - LLEnvironmentRequest::initiate(); - // *TODO: Indicate that current cached region settings have been invalidated? -} - void LLEnvManagerNew::onRegionChange(bool interpolate) { // Avoid duplicating region setting requests @@ -816,22 +875,8 @@ void LLEnvManagerNew::onRegionChange(bool interpolate) LL_DEBUGS("Windlight") << "New viewer region: " << region_uuid << LL_ENDL; mCurRegionUUID = region_uuid; mInterpNextChangeMessage = interpolate; - sendRegionSettingsRequest(); -} + requestRegionSettings(); -void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content) -{ - // 1. Refresh cached region settings. - LL_DEBUGS("Windlight") << "Caching region environment settings: " << content << LL_ENDL; - F32 sun_hour = 0; // *TODO - LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour); - mCachedRegionPrefs = new_settings; - - // 2. If using server settings, update managers. - if (getUseRegionSettings()) - { - updateManagersFromPrefs(mInterpNextChangeMessage); - } - - mInterpNextChangeMessage = false; + // Let interested parties know agent region has been changed. + mRegionChangeSignal(); } diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h index 1f005ecce2..52b645b535 100644 --- a/indra/newview/llenvmanager.h +++ b/indra/newview/llenvmanager.h @@ -99,7 +99,7 @@ public: return mDayTime; } - LLSD makePacket(const LLSD& metadata) + LLSD makePacket(const LLSD& metadata) const { LLSD full_packet = LLSD::emptyArray(); @@ -259,21 +259,30 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew> { LOG_CLASS(LLEnvManagerNew); public: + typedef boost::signals2::signal<void()> region_settings_change_signal_t; + typedef boost::signals2::signal<void()> region_change_signal_t; + typedef boost::signals2::signal<void(bool)> region_settings_applied_signal_t; + LLEnvManagerNew(); + // getters to access user env. preferences bool getUseRegionSettings() const; bool getUseDayCycle() const; bool getUseFixedSky() const; std::string getWaterPresetName() const; std::string getSkyPresetName() const; std::string getDayCycleName() const; + + /// @return cached env. settings of the current region. const LLEnvironmentSettings& getRegionSettings() const; + // setters for user env. preferences void setUseRegionSettings(bool val); void setUseWaterPreset(const std::string& name); void setUseSkyPreset(const std::string& name); void setUseDayCycle(const std::string& name); + // Preferences manipulation. void loadUserPrefs(); void saveUserPrefs(); void setUserPrefs( @@ -284,23 +293,44 @@ public: bool use_region_settings); void dumpUserPrefs(); + // Common interface to the wl/water managers. + static LLSD getDayCycleByName(const std::string name); + + // Misc. + void requestRegionSettings(); + bool sendRegionSettings(const LLEnvironmentSettings& new_settings); + boost::signals2::connection setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb); + boost::signals2::connection setRegionChangeCallback(const region_change_signal_t::slot_type& cb); + boost::signals2::connection setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb); + + // Public callbacks. void onRegionCrossing(); void onTeleport(); void onRegionSettingsResponse(const LLSD& content); + void onRegionSettingsApplyResponse(bool ok); private: friend class LLSingleton<LLEnvManagerNew>; /*virtual*/ void initSingleton(); void updateManagersFromPrefs(bool interpolate); - void sendRegionSettingsRequest(); void onRegionChange(bool interpolate); + /// Emitted when region environment settings update comes. + region_settings_change_signal_t mRegionSettingsChangeSignal; + + /// Emitted when agent region changes. Move to LLAgent? + region_settings_change_signal_t mRegionChangeSignal; + + /// Emitted when agent region changes. Move to LLAgent? + region_settings_applied_signal_t mRegionSettingsAppliedSignal; + LLEnvPrefs mUserPrefs; /// User environment preferences. LLEnvironmentSettings mCachedRegionPrefs; /// Cached region environment settings. bool mInterpNextChangeMessage; /// Interpolate env. settings on next region change. LLUUID mCurRegionUUID; /// To avoid duplicated region env. settings requests. + LLUUID mLastReceivedID; /// Id of last received region env. settings. }; #endif // LL_LLENVMANAGER_H diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index ce7453e2dc..f789a761eb 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -40,6 +40,8 @@ #include "llxfermanager.h" #include "indra_constants.h" #include "message.h" +#include "llloadingindicator.h" +#include "llradiogroup.h" #include "llsd.h" #include "llsdserialize.h" @@ -84,6 +86,7 @@ #include "llviewertexteditor.h" #include "llviewerwindow.h" #include "llvlcomposition.h" +#include "llwaterparammanager.h" #include "lltrans.h" #include "llagentui.h" @@ -198,6 +201,7 @@ LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) BOOL LLFloaterRegionInfo::postBuild() { mTab = getChild<LLTabContainer>("region_panels"); + mTab->setCommitCallback(boost::bind(&LLFloaterRegionInfo::onTabSelected, this, _2)); // contruct the panels LLPanelRegionInfo* panel; @@ -237,6 +241,9 @@ BOOL LLFloaterRegionInfo::postBuild() "EstateOwnerMessage", &processEstateOwnerRequest); + // Request region info when agent region changes. + LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this)); + return TRUE; } @@ -313,6 +320,8 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) // static void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) { + LL_DEBUGS("Windlight") << "Processing region info" << LL_ENDL; + LLPanel* panel; LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; @@ -320,11 +329,12 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) { return; } - - - // currently, region can send this message when its windlight settings change - LLEnvManager::instance().refreshFromStorage(LLEnvKey::SCOPE_REGION); + // We need to re-request environment setting here, + // otherwise after we apply (send) updated region settings we won't get them back, + // so our environment won't be updated. + LLEnvManagerNew::instance().requestRegionSettings(); + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); LLViewerRegion* region = gAgent.getRegion(); @@ -447,6 +457,12 @@ LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain() return panel; } +void LLFloaterRegionInfo::onTabSelected(const LLSD& param) +{ + LLPanel* active_panel = getChild<LLPanel>(param.asString()); + active_panel->onOpen(LLSD()); +} + void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) { if (!region) @@ -3241,3 +3257,340 @@ bool LLDispatchSetEstateAccess::operator()( return true; } + +LLPanelEnvironmentInfo::LLPanelEnvironmentInfo() +: mEnableEditing(false), + mRegionSettingsRadioGroup(NULL), + mDayCycleSettingsRadioGroup(NULL), + mWaterPresetCombo(NULL), + mSkyPresetCombo(NULL), + mDayCyclePresetCombo(NULL) +{ +} + +// virtual +BOOL LLPanelEnvironmentInfo::postBuild() +{ + mRegionSettingsRadioGroup = getChild<LLRadioGroup>("region_settings_radio_group"); + mRegionSettingsRadioGroup->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSwitchRegionSettings, this)); + + mDayCycleSettingsRadioGroup = getChild<LLRadioGroup>("sky_dayc_settings_radio_group"); + mDayCycleSettingsRadioGroup->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSwitchDayCycle, this)); + + mWaterPresetCombo = getChild<LLComboBox>("water_settings_preset_combo"); + mSkyPresetCombo = getChild<LLComboBox>("sky_settings_preset_combo"); + mDayCyclePresetCombo = getChild<LLComboBox>("dayc_settings_preset_combo"); + + childSetCommitCallback("save_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnSave, this), NULL); + childSetCommitCallback("cancel_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnCancel, this), NULL); + + LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingschange, this)); + LLEnvManagerNew::instance().setRegionSettingsAppliedCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingsApplied, this, _1)); + + return TRUE; +} + +// virtual +void LLPanelEnvironmentInfo::onOpen(const LLSD& key) +{ + LL_DEBUGS("Windlight") << "Panel opened, refreshing" << LL_ENDL; + refresh(); +} + +// virtual +bool LLPanelEnvironmentInfo::refreshFromRegion(LLViewerRegion* region) +{ + LL_DEBUGS("Windlight") << "Region updated, enabling/disabling controls" << LL_ENDL; + BOOL owner_or_god = gAgent.isGodlike() || (region && (region->getOwner() == gAgent.getID())); + BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager()); + + // Don't refresh from region settings to avoid flicker after applying new region settings. + mEnableEditing = owner_or_god_or_manager; + setControlsEnabled(mEnableEditing); + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +void LLPanelEnvironmentInfo::refresh() +{ + populateWaterPresetsList(); + populateSkyPresetsList(); + populateDayCyclesList(); + + // Init radio groups. + const LLEnvironmentSettings& settings = LLEnvManagerNew::instance().getRegionSettings(); + const LLSD& dc = settings.getWLDayCycle(); + LLSD::Real first_frame_time = dc.size() > 0 ? dc[0][0].asReal() : 0.0f; + const bool use_fixed_sky = dc.size() == 1 && first_frame_time < 0; + mRegionSettingsRadioGroup->setSelectedIndex(settings.getSkyMap().size() == 0 ? 0 : 1); + mDayCycleSettingsRadioGroup->setSelectedIndex(use_fixed_sky ? 0 : 1); + + setControlsEnabled(mEnableEditing); +} + +void LLPanelEnvironmentInfo::setControlsEnabled(bool enabled) +{ + mRegionSettingsRadioGroup->setEnabled(enabled); + mDayCycleSettingsRadioGroup->setEnabled(enabled); + + mWaterPresetCombo->setEnabled(enabled); + mSkyPresetCombo->setEnabled(enabled); + mDayCyclePresetCombo->setEnabled(enabled); + + getChildView("save_btn")->setEnabled(enabled); + getChildView("cancel_btn")->setEnabled(enabled); + + if (enabled) + { + // Enable/disable some controls based on currently selected radio buttons. + LLPanelEnvironmentInfo::onSwitchRegionSettings(); + LLPanelEnvironmentInfo::onSwitchDayCycle(); + } +} + +void LLPanelEnvironmentInfo::setApplyProgress(bool started) +{ + LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator"); + + indicator->setVisible(started); + + if (started) + { + indicator->start(); + } + else + { + indicator->stop(); + } +} + +void LLPanelEnvironmentInfo::populateWaterPresetsList() +{ + mWaterPresetCombo->removeall(); + + // If the region already has water params, add them to the list. + const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings(); + if (region_settings.getWaterParams().size() != 0) + { + const std::string& region_name = gAgent.getRegion()->getName(); + mWaterPresetCombo->add(region_name, LLWLParamKey(region_name, LLEnvKey::SCOPE_REGION).toLLSD()); + mWaterPresetCombo->addSeparator(); + } + + // Add local water presets. + const std::map<std::string, LLWaterParamSet> &water_params_map = LLWaterParamManager::instance().mParamList; + for (std::map<std::string, LLWaterParamSet>::const_iterator it = water_params_map.begin(); it != water_params_map.end(); it++) + { + mWaterPresetCombo->add(it->first, LLWLParamKey(it->first, LLEnvKey::SCOPE_LOCAL).toLLSD()); + } + + // There's no way to select current preset because its name is not stored on server. +} + +void LLPanelEnvironmentInfo::populateSkyPresetsList() +{ + mSkyPresetCombo->removeall(); + + const std::map<LLWLParamKey, LLWLParamSet> &sky_params_map = LLWLParamManager::getInstance()->mParamList; + for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = sky_params_map.begin(); it != sky_params_map.end(); it++) + { + std::string preset_name = it->first.name; + std::string item_title; + + if (it->first.scope == LLEnvKey::SCOPE_LOCAL) // local preset + { + item_title = preset_name; + } + else // region preset + { + item_title = preset_name + " (" + gAgent.getRegion()->getName() + ")"; + } + + // Saving as string instead of LLSD() for selectByValue() to work, as it doesn't support non-scalar values. + mSkyPresetCombo->add(item_title, it->first.toStringVal()); + } + + // Select current preset. + LLSD sky_map = LLEnvManagerNew::instance().getRegionSettings().getSkyMap(); + if (sky_map.size() == 1) // if the region is set to fixed sky + { + std::string preset_name = sky_map.beginMap()->first; + mSkyPresetCombo->selectByValue(LLWLParamKey(preset_name, LLEnvKey::SCOPE_REGION).toStringVal()); + } +} + +void LLPanelEnvironmentInfo::populateDayCyclesList() +{ + mDayCyclePresetCombo->removeall(); + + // If the region already has env. settings, add its day cycle to the list. + const LLSD& cur_region_dc = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle(); + if (cur_region_dc.size() != 0) + { + LLViewerRegion* region = gAgent.getRegion(); + llassert(region != NULL); + + LLWLParamKey key(region->getName(), LLEnvKey::SCOPE_REGION); + mDayCyclePresetCombo->add(region->getName(), key.toLLSD()); + mDayCyclePresetCombo->addSeparator(); + } + + // Add local day cycles. + // *TODO: multiple local day cycles support + LLWLParamKey key("Default", LLEnvKey::SCOPE_LOCAL); + mDayCyclePresetCombo->add("Default", key.toLLSD()); + + // Current day cycle is already selected. +} + +void LLPanelEnvironmentInfo::onSwitchRegionSettings() +{ + getChild<LLView>("user_environment_settings")->setEnabled(mRegionSettingsRadioGroup->getSelectedIndex() != 0); +} + +void LLPanelEnvironmentInfo::onSwitchDayCycle() +{ + bool is_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0; + + mSkyPresetCombo->setEnabled(is_fixed_sky); + mDayCyclePresetCombo->setEnabled(!is_fixed_sky); +} + +void LLPanelEnvironmentInfo::onBtnSave() +{ + LL_DEBUGS("Windlight") << "About to save region settings" << LL_ENDL; + + const LLEnvironmentSettings& old_region_settings = LLEnvManagerNew::instance().getRegionSettings(); + const bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0; + const bool use_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0; + + LLSD day_cycle; + LLSD sky_map; + LLSD water_params; + + if (use_defaults) + { + // settings will be empty + LL_DEBUGS("Windlight") << "Defaults" << LL_ENDL; + } + else // use custom region settings + { + if (use_fixed_sky) + { + LL_DEBUGS("Windlight") << "Use fixed sky" << LL_ENDL; + std::string preset_key(mSkyPresetCombo->getValue().asString()); + LLWLParamKey preset(preset_key); + + // Get the preset sky params. + LLWLParamSet params; + if (!LLWLParamManager::instance().getParamSet(preset, params)) + { + llwarns << "Error getting sky params: " << preset.toLLSD() << llendl; + return; + } + + // Create a day cycle consisting of a single sky preset. + LLSD key(LLSD::emptyArray()); + key.append(-1.0f); // indicate that user preference is actually fixed sky, not a day cycle + key.append(preset.name); + day_cycle.append(key); + + // Create a sky map consisting of only the sky preset. + std::map<LLWLParamKey, LLWLParamSet> refs; + refs[preset] = params; + sky_map = LLWLParamManager::createSkyMap(refs); + } + else // use day cycle + { + LLWLParamKey dc(mDayCyclePresetCombo->getValue()); + LL_DEBUGS("Windlight") << "Use day cycle: " << dc.toLLSD() << LL_ENDL; + + if (dc.scope == LLEnvKey::SCOPE_REGION) // current region day cycle + { + day_cycle = old_region_settings.getWLDayCycle(); + sky_map = old_region_settings.getSkyMap(); + } + else // a local day cycle + { + // *TODO: multiple local day cycles support + day_cycle = LLEnvManagerNew::instance().getDayCycleByName("Default"); + + // Create sky map from the day cycle. + { + std::map<LLWLParamKey, LLWLParamSet> refs; + LLWLDayCycle tmp_day; + + tmp_day.loadDayCycle(day_cycle, dc.scope); + tmp_day.getSkyRefs(refs); + + sky_map = LLWLParamManager::createSkyMap(refs); + } + + LL_DEBUGS("Windlight") << "day_cycle: " << day_cycle << LL_ENDL; + LL_DEBUGS("Windlight") << "sky_map: " << sky_map << LL_ENDL; + } + } + + // Get water params. + LLWLParamKey water_key(mWaterPresetCombo->getSelectedValue()); + if (water_key.scope == LLEnvKey::SCOPE_REGION) + { + water_params = old_region_settings.getWaterParams(); + } + else + { + LLWaterParamSet param_set; + if (!LLWaterParamManager::instance().getParamSet(water_key.name, param_set)) + { + llwarns << "Error getting water preset: " << water_key.name << llendl; + return; + } + + water_params = param_set.getAll(); + } + } + + // Send settings apply request. + LLEnvironmentSettings new_region_settings; + new_region_settings.saveParams(day_cycle, sky_map, water_params, 0.0f); + if (!LLEnvManagerNew::instance().sendRegionSettings(new_region_settings)) + { + llwarns << "Error applying region environment settings" << llendl; + return; + } + + setApplyProgress(true); +} + +void LLPanelEnvironmentInfo::onBtnCancel() +{ + // Reload current region settings. + refresh(); +} + +void LLPanelEnvironmentInfo::onRegionSettingschange() +{ + LL_DEBUGS("Windlight") << "Region settings changed, refreshing" << LL_ENDL; + refresh(); + + // Stop applying progress indicator (it may be running if it's us who initiated settings update). + setApplyProgress(false); +} + +void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok) +{ + LL_DEBUGS("Windlight") << "Applying region settings finished, stopping indicator" << LL_ENDL; + // If applying new settings has failed, stop the indicator right away. + // Otherwise it will be stopped when we receive the updated settings from server. + if (!ok) + { + setApplyProgress(false); + + // We need to re-request environment setting here, + // otherwise our subsequent attempts to change region settings will fail with the following error: + // "Unable to update environment settings because the last update your viewer saw was not the same + // as the last update sent from the simulator. Try sending your update again, and if this + // does not work, try leaving and returning to the region." + LLEnvManagerNew::instance().requestRegionSettings(); + } +} diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 2496955632..31b68ec030 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -46,6 +46,7 @@ class LLInventoryItem; class LLCheckBoxCtrl; class LLComboBox; class LLNameListCtrl; +class LLRadioGroup; class LLSliderCtrl; class LLSpinCtrl; class LLTextBox; @@ -105,6 +106,7 @@ private: boost::signals2::connection mConsoleReplySignalConnection;; protected: + void onTabSelected(const LLSD& param); void refreshFromRegion(LLViewerRegion* region); // member data @@ -427,6 +429,44 @@ protected: class LLPanelEnvironmentInfo : public LLPanelRegionInfo { + LOG_CLASS(LLPanelEnvironmentInfo); + +public: + LLPanelEnvironmentInfo(); + + // LLPanel + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + + // LLPanelRegionInfo + /*virtual*/ bool refreshFromRegion(LLViewerRegion* region); + +private: + void refresh(); + void setControlsEnabled(bool enabled); + void setApplyProgress(bool started); + + void populateWaterPresetsList(); + void populateSkyPresetsList(); + void populateDayCyclesList(); + + void onSwitchRegionSettings(); + void onSwitchDayCycle(); + + void onBtnSave(); + void onBtnCancel(); + + void onRegionSettingschange(); + void onRegionSettingsApplied(bool ok); + + bool mEnableEditing; + + LLRadioGroup* mRegionSettingsRadioGroup; + LLRadioGroup* mDayCycleSettingsRadioGroup; + + LLComboBox* mWaterPresetCombo; + LLComboBox* mSkyPresetCombo; + LLComboBox* mDayCyclePresetCombo; }; #endif diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp index 05f7fd9872..7363392042 100644 --- a/indra/newview/llwldaycycle.cpp +++ b/indra/newview/llwldaycycle.cpp @@ -146,6 +146,25 @@ LLSD LLWLDayCycle::asLLSD() return day_data; } +bool LLWLDayCycle::getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) +{ + bool result = true; + LLWLParamManager& wl_mgr = LLWLParamManager::instance(); + + refs.clear(); + for (std::map<F32, LLWLParamKey>::iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter) + { + LLWLParamKey& key = iter->second; + if (!wl_mgr.getParamSet(key, refs[key])) + { + llwarns << "Cannot find sky [" << key.name << "] referenced by a day cycle" << llendl; + result = false; + } + } + + return result; +} + void LLWLDayCycle::clearKeyframes() { lldebugs << "Clearing key frames" << llendl; diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h index 988003c1af..36b5160a58 100644 --- a/indra/newview/llwldaycycle.h +++ b/indra/newview/llwldaycycle.h @@ -71,6 +71,9 @@ public: /// get the LLSD data for this day cycle LLSD asLLSD(); + // get skies referenced by this day cycle + bool getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs); + /// clear keyframes void clearKeyframes(); diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index 905b8d83a8..b5f53232cc 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -127,21 +127,20 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD()); } - /**** - * LLEnvironmentApplyResponder + * LLEnvironmentApply ****/ -clock_t LLEnvironmentApplyResponder::UPDATE_WAIT_SECONDS = clock_t(3.f); -clock_t LLEnvironmentApplyResponder::sLastUpdate = clock_t(0.f); -bool LLEnvironmentApplyResponder::initiateRequest(const LLSD& content) +clock_t LLEnvironmentApply::UPDATE_WAIT_SECONDS = clock_t(3.f); +clock_t LLEnvironmentApply::sLastUpdate = clock_t(0.f); + +// static +bool LLEnvironmentApply::initiateRequest(const LLSD& content) { clock_t current = clock(); - if(current >= sLastUpdate + (UPDATE_WAIT_SECONDS * CLOCKS_PER_SEC)) - { - sLastUpdate = current; - } - else + + // Make sure we don't update too frequently. + if (current < sLastUpdate + (UPDATE_WAIT_SECONDS * CLOCKS_PER_SEC)) { LLSD args(LLSD::emptyMap()); args["WAIT"] = (F64)UPDATE_WAIT_SECONDS; @@ -149,20 +148,25 @@ bool LLEnvironmentApplyResponder::initiateRequest(const LLSD& content) return false; } + sLastUpdate = current; + + // Send update request. std::string url = gAgent.getRegion()->getCapability("EnvironmentSettings"); - if (!url.empty()) - { - LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL; - LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL; - LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder()); - return true; - } - else + if (url.empty()) { LL_WARNS("WindlightCaps") << "Applying windlight settings not supported" << LL_ENDL; + return false; } - return false; + + LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL; + LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL; + LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder()); + return true; } + +/**** + * LLEnvironmentApplyResponder + ****/ /*virtual*/ void LLEnvironmentApplyResponder::result(const LLSD& content) { if (content["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) @@ -175,6 +179,7 @@ bool LLEnvironmentApplyResponder::initiateRequest(const LLSD& content) else if (content["success"].asBoolean()) { LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << content["regionID"].asUUID() << LL_ENDL; + LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true); } else { @@ -182,9 +187,8 @@ bool LLEnvironmentApplyResponder::initiateRequest(const LLSD& content) LLSD args(LLSD::emptyMap()); args["FAIL_REASON"] = content["fail_reason"].asString(); LLNotificationsUtil::add("WLRegionApplyFail", args); + LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false); } - - LLEnvManager::getInstance()->commitSettingsFinished(LLEnvKey::SCOPE_REGION); } /*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason) { @@ -196,6 +200,4 @@ bool LLEnvironmentApplyResponder::initiateRequest(const LLSD& content) LLSD args(LLSD::emptyMap()); args["FAIL_REASON"] = msg.str(); LLNotificationsUtil::add("WLRegionApplyFail", args); - - LLEnvManager::getInstance()->commitSettingsFinished(LLEnvKey::SCOPE_REGION); } diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h index 05b2244e8a..b5eb62b0b0 100644 --- a/indra/newview/llwlhandlers.h +++ b/indra/newview/llwlhandlers.h @@ -66,6 +66,18 @@ private: int mID; }; +class LLEnvironmentApply +{ + LOG_CLASS(LLEnvironmentApply); +public: + /// @return true if request was successfully sent + static bool initiateRequest(const LLSD& content); + +private: + static clock_t sLastUpdate; + static clock_t UPDATE_WAIT_SECONDS; +}; + class LLEnvironmentApplyResponder: public LLHTTPClient::Responder { LOG_CLASS(LLEnvironmentApplyResponder); @@ -89,14 +101,8 @@ public: virtual void error(U32 status, const std::string& reason); // non-200 errors only private: - friend class LLEnvManager; + friend class LLEnvironmentApply; - static clock_t sLastUpdate; - static clock_t UPDATE_WAIT_SECONDS; - - // for format of packet expected, see llwlscrubbers.cpp in llmessage - static bool initiateRequest(const LLSD& packet); - LLEnvironmentApplyResponder() {} }; diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index d64e2420e4..ec7889cb93 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -234,6 +234,7 @@ std::map<LLWLParamKey, LLWLParamSet> LLWLParamManager::finalizeFromDayCycle(LLWL return final_references; } +// static LLSD LLWLParamManager::createSkyMap(std::map<LLWLParamKey, LLWLParamSet> refs) { LLSD skies = LLSD::emptyMap(); @@ -588,10 +589,12 @@ void LLWLParamManager::applyUserPrefs(bool interpolate) // Remove all region sky presets because they may belong to a previously visited region. clearParamSetsOfScope(LLEnvKey::SCOPE_REGION); + // Add all sky presets belonging to the current region. + const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings(); + addAllSkies(LLEnvKey::SCOPE_REGION, region_settings.getSkyMap()); + if (LLEnvManagerNew::instance().getUseRegionSettings()) // apply region-wide settings { - const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings(); - if (region_settings.getSkyMap().size() == 0) { applyDefaults(); @@ -601,9 +604,6 @@ void LLWLParamManager::applyUserPrefs(bool interpolate) // *TODO: Support fixed sky from region. LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL; - // Add all sky presets belonging to the current region. - addAllSkies(LLEnvKey::SCOPE_REGION, region_settings.getSkyMap()); - // Apply region day cycle. mDay.loadDayCycle(region_settings.getWLDayCycle(), LLEnvKey::SCOPE_REGION); resetAnimator(region_settings.getDayTime(), true); diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index 2f1edce8fc..35acb7c5d6 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -144,9 +144,13 @@ public: } inline LLWLParamKey(std::string& stringVal) - : name(stringVal.substr(0, stringVal.length()-1)), - scope((EScope)atoi(stringVal.substr(stringVal.length()-1, stringVal.length()).c_str())) { + size_t len = stringVal.length(); + if (len > 0) + { + name = stringVal.substr(0, len - 1); + scope = (EScope) atoi(stringVal.substr(len - 1, len).c_str()); + } } inline std::string toStringVal() const @@ -289,7 +293,7 @@ public: std::map<LLWLParamKey, LLWLParamSet> finalizeFromDayCycle(LLWLParamKey::EScope scope); // returns all skies in map (intended to be called with output from a finalize) - LLSD createSkyMap(std::map<LLWLParamKey, LLWLParamSet> map); + static LLSD createSkyMap(std::map<LLWLParamKey, LLWLParamSet> map); // helper variables LLWLAnimator mAnimator; diff --git a/indra/newview/skins/default/xui/en/panel_region_environment.xml b/indra/newview/skins/default/xui/en/panel_region_environment.xml index 907a707db8..956ba53a26 100644 --- a/indra/newview/skins/default/xui/en/panel_region_environment.xml +++ b/indra/newview/skins/default/xui/en/panel_region_environment.xml @@ -137,4 +137,11 @@ left_pad="10" name="cancel_btn" width="100" /> + <loading_indicator + height="23" + left="10" + name="progress_indicator" + top_delta="0" + visible="false" + width="23" /> </panel> |