llsettingsbase.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. /**
  2. * @file llsettingsbase.h
  3. * @brief A base class for asset based settings groups.
  4. *
  5. * $LicenseInfo:firstyear=2018&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2019, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_SETTINGSBASE_H
  33. #define LL_SETTINGSBASE_H
  34. #include <memory>
  35. #include <vector>
  36. #include "boost/function.hpp"
  37. #include "boost/signals2.hpp"
  38. #include "llcolor3.h"
  39. #include "llcolor4.h"
  40. #include "hbfastmap.h"
  41. #include "hbfastset.h"
  42. #include "llquaternion.h"
  43. #include "llsettingstype.h"
  44. #include "llsdutil.h"
  45. #include "lltimer.h"
  46. #include "lluuid.h"
  47. #include "llvector4.h"
  48. class LLShaderUniforms;
  49. constexpr F32 INVALID_TRACKPOS = -1.f;
  50. class LLSettingsBase : public std::enable_shared_from_this<LLSettingsBase>
  51. {
  52. friend class LLEnvironment;
  53. friend class LLSettingsDay;
  54. friend std::ostream& operator<<(std::ostream& os, LLSettingsBase& set);
  55. protected:
  56. LOG_CLASS(LLSettingsBase);
  57. LLSettingsBase();
  58. LLSettingsBase(const LLSD& setting);
  59. public:
  60. virtual ~LLSettingsBase() = default;
  61. // Non-copyable
  62. LLSettingsBase(const LLSettingsBase&) = delete;
  63. LLSettingsBase& operator=(const LLSettingsBase&) = delete;
  64. static constexpr U32 FLAG_NOCOPY = 1;
  65. static constexpr U32 FLAG_NOMOD = 2;
  66. static constexpr U32 FLAG_NOTRANS = 4;
  67. static constexpr U32 FLAG_NOSAVE = 8;
  68. static const std::string SETTING_ID;
  69. static const std::string SETTING_NAME;
  70. static const std::string SETTING_HASH;
  71. static const std::string SETTING_TYPE;
  72. static const std::string SETTING_ASSETID;
  73. static const std::string SETTING_FLAGS;
  74. class DefaultParam
  75. {
  76. public:
  77. DefaultParam(S32 key, const LLSD& value)
  78. : mShaderKey(key),
  79. mDefaultValue(value)
  80. {
  81. }
  82. DefaultParam()
  83. : mShaderKey(-1)
  84. {
  85. }
  86. LL_INLINE S32 getShaderKey() const { return mShaderKey; }
  87. LL_INLINE const LLSD getDefaultValue() const { return mDefaultValue; }
  88. private:
  89. S32 mShaderKey;
  90. LLSD mDefaultValue;
  91. };
  92. // Contains settings' names (map key), related shader id-key and default
  93. // value for revert in case we need to reset shader (no need to search
  94. // each time)
  95. typedef flat_hmap<std::string, DefaultParam> parammapping_t;
  96. virtual std::string getSettingsType() const = 0;
  97. virtual LLSettingsType::EType getSettingsTypeValue() const = 0;
  98. // Settings status
  99. LL_INLINE bool hasSetting(const std::string& param) const
  100. {
  101. return mSettings.has(param);
  102. }
  103. LL_INLINE virtual bool isDirty() const { return mDirty; }
  104. LL_INLINE virtual bool isVeryDirty() const { return mReplaced; }
  105. LL_INLINE void setDirtyFlag(bool dirty)
  106. {
  107. mDirty = dirty;
  108. clearAssetId();
  109. }
  110. // Hash will not include Name, ID or a previously stored Hash
  111. size_t getHash() const;
  112. LL_INLINE LLUUID getId() const
  113. {
  114. return getValue(SETTING_ID).asUUID();
  115. }
  116. LL_INLINE std::string getName() const
  117. {
  118. return getValue(SETTING_NAME).asString();
  119. }
  120. LL_INLINE void setName(std::string val)
  121. {
  122. setValue(SETTING_NAME, val);
  123. }
  124. LL_INLINE LLUUID getAssetId() const
  125. {
  126. if (mSettings.has(SETTING_ASSETID))
  127. {
  128. return mSettings[SETTING_ASSETID].asUUID();
  129. }
  130. return LLUUID::null;
  131. }
  132. LL_INLINE U32 getFlags() const
  133. {
  134. if (mSettings.has(SETTING_FLAGS))
  135. {
  136. return mSettings[SETTING_FLAGS].asInteger();
  137. }
  138. return 0;
  139. }
  140. LL_INLINE void setFlags(U32 value)
  141. {
  142. setLLSD(SETTING_FLAGS, LLSD::Integer(value));
  143. }
  144. LL_INLINE bool getFlag(U32 flag) const
  145. {
  146. return mSettings.has(SETTING_FLAGS) &&
  147. ((U32)mSettings[SETTING_FLAGS].asInteger() & flag) == flag;
  148. }
  149. LL_INLINE void setFlag(U32 flag)
  150. {
  151. U32 flags = flag;
  152. if (mSettings.has(SETTING_FLAGS))
  153. {
  154. flags |= (U32)mSettings[SETTING_FLAGS].asInteger();
  155. }
  156. if (flags)
  157. {
  158. mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
  159. }
  160. else
  161. {
  162. mSettings.erase(SETTING_FLAGS);
  163. }
  164. }
  165. LL_INLINE void clearFlag(U32 flag)
  166. {
  167. U32 flags = 0;
  168. if (mSettings.has(SETTING_FLAGS))
  169. {
  170. flags &= (U32)mSettings[SETTING_FLAGS].asInteger();
  171. }
  172. if (flags)
  173. {
  174. mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
  175. }
  176. else
  177. {
  178. mSettings.erase(SETTING_FLAGS);
  179. }
  180. }
  181. LL_INLINE virtual void replaceSettings(const LLSD& settings)
  182. {
  183. mBlendedFactor = 0.0;
  184. setDirtyFlag(true);
  185. mReplaced = true;
  186. mSettings = settings;
  187. }
  188. LL_INLINE virtual LLSD getSettings() const { return mSettings; }
  189. LL_INLINE void setLLSD(const std::string& name, const LLSD& value)
  190. {
  191. mSettings[name] = value;
  192. mDirty = true;
  193. if (name != SETTING_ASSETID)
  194. {
  195. clearAssetId();
  196. }
  197. }
  198. LL_INLINE void setValue(const std::string& name, const LLSD& value)
  199. {
  200. setLLSD(name, value);
  201. }
  202. LL_INLINE LLSD getValue(const std::string& name,
  203. const LLSD& deflt = LLSD()) const
  204. {
  205. return mSettings.has(name) ? mSettings[name] : deflt;
  206. }
  207. LL_INLINE void setValue(const std::string& name, F32 v)
  208. {
  209. setLLSD(name, LLSD::Real(v));
  210. }
  211. LL_INLINE void setValue(const std::string& name, const LLVector2& value)
  212. {
  213. setValue(name, value.getValue());
  214. }
  215. LL_INLINE void setValue(const std::string& name, const LLVector3& value)
  216. {
  217. setValue(name, value.getValue());
  218. }
  219. LL_INLINE void setValue(const std::string& name, const LLVector4& value)
  220. {
  221. setValue(name, value.getValue());
  222. }
  223. LL_INLINE void setValue(const std::string& name, const LLQuaternion& value)
  224. {
  225. setValue(name, value.getValue());
  226. }
  227. LL_INLINE void setValue(const std::string& name, const LLColor3& value)
  228. {
  229. setValue(name, value.getValue());
  230. }
  231. LL_INLINE void setValue(const std::string& name, const LLColor4& value)
  232. {
  233. setValue(name, value.getValue());
  234. }
  235. LL_INLINE F64 getBlendFactor() const { return mBlendedFactor; }
  236. // Note this method is marked const but may modify the settings object
  237. // (note the internal cast). This is so that it may be called without
  238. // special consideration from getters.
  239. LL_INLINE void update() const
  240. {
  241. if (mDirty || mReplaced)
  242. {
  243. ((LLSettingsBase*)this)->updateSettings();
  244. }
  245. }
  246. typedef std::shared_ptr<LLSettingsBase> ptr_t;
  247. virtual void blend(const ptr_t& end, F64 blendf) = 0;
  248. virtual bool validate();
  249. virtual ptr_t buildDerivedClone() const = 0;
  250. class Validator
  251. {
  252. public:
  253. static constexpr U32 VALIDATION_PARTIAL = 1;
  254. typedef boost::function<bool(LLSD&, U32)> verify_pr;
  255. Validator(const std::string& name, bool required, LLSD::Type type,
  256. verify_pr verify = verify_pr(), const LLSD& defval = LLSD())
  257. : mName(name),
  258. mRequired(required),
  259. mType(type),
  260. mVerify(verify),
  261. mDefault(defval)
  262. {
  263. }
  264. LL_INLINE std::string getName() const { return mName; }
  265. LL_INLINE bool isRequired() const { return mRequired; }
  266. LL_INLINE LLSD::Type getType() const { return mType; }
  267. bool verify(LLSD& data, U32 flags) const;
  268. // Some basic verifications
  269. static bool verifyColor(LLSD& value, U32 flags);
  270. static bool verifyVector(LLSD& value, U32 flags, size_t length);
  271. static bool verifyVectorMinMax(LLSD& value, U32 flags, LLSD minvals,
  272. LLSD maxvals);
  273. static bool verifyVectorNormalized(LLSD& value, U32 flags,
  274. size_t length);
  275. static bool verifyQuaternion(LLSD& value, U32 flags);
  276. static bool verifyQuaternionNormal(LLSD& value, U32 flags);
  277. static bool verifyFloatRange(LLSD& value, U32 flags, LLSD range);
  278. static bool verifyIntegerRange(LLSD& value, U32 flags, LLSD range);
  279. static bool verifyStringLength(LLSD& value, U32 flags, size_t length);
  280. private:
  281. LLSD::Type mType;
  282. verify_pr mVerify;
  283. std::string mName;
  284. LLSD mDefault;
  285. bool mRequired;
  286. };
  287. typedef std::vector<Validator> validation_list_t;
  288. static LLSD settingValidation(LLSD& settings,
  289. const validation_list_t& validations,
  290. bool partial = false);
  291. LL_INLINE void setAssetId(const LLUUID& value)
  292. {
  293. // Note that this skips setLLSD
  294. mSettings[SETTING_ASSETID] = value;
  295. }
  296. LL_INLINE void clearAssetId()
  297. {
  298. if (mSettings.has(SETTING_ASSETID))
  299. {
  300. mSettings.erase(SETTING_ASSETID);
  301. }
  302. }
  303. // Calculate any custom settings that may need to be cached.
  304. LL_INLINE virtual void updateSettings() { mDirty = mReplaced = false; }
  305. protected:
  306. typedef flat_hset<std::string> stringset_t;
  307. // Combining settings objects. Customize for specific setting types
  308. virtual void lerpSettings(const LLSettingsBase& other, F64 mix);
  309. // Combine settings maps where it can, based on mix rate.
  310. // - 'settings' is initial value (mix==0)
  311. // - 'other' is target value (mix==1)
  312. // - 'defaults' is a list of default values for legacy fields and
  313. // (re)setting shaders
  314. // - 'mix' from 0 to 1, is the ratio or rate of transition from initial
  315. // 'settings' to 'other'
  316. // Return interpolated and combined LLSD map.
  317. LLSD interpolateSDMap(const LLSD& settings, const LLSD& other,
  318. const parammapping_t& defaults, F64 mix) const;
  319. virtual LLSD interpolateSDValue(const std::string& name, const LLSD& value,
  320. const LLSD& other,
  321. const parammapping_t& defaults,
  322. F64 mix, const stringset_t& slerps) const;
  323. // When lerping between settings, some may require special handling.
  324. // This method gets a list of these key to be skipped by the default
  325. // settings lerp (handling should be performed in the override of
  326. // lerpSettings).
  327. virtual const stringset_t& getSkipInterpolateKeys() const;
  328. // A list of settings that represent quaternions and should be slerped
  329. // rather than lerped.
  330. virtual const stringset_t& getSlerpKeys() const;
  331. virtual const parammapping_t& getParameterMap() const;
  332. virtual const validation_list_t& getValidationList() const = 0;
  333. // Apply any settings that need special handling.
  334. LL_INLINE virtual void applySpecial(LLShaderUniforms* uniforms)
  335. {
  336. }
  337. LL_INLINE void setBlendFactor(F64 factor) { mBlendedFactor = factor; }
  338. LL_INLINE void replaceWith(LLSettingsBase::ptr_t other)
  339. {
  340. replaceSettings(other->cloneSettings());
  341. setBlendFactor(other->getBlendFactor());
  342. }
  343. LLSD cloneSettings() const;
  344. private:
  345. LLSD combineSDMaps(const LLSD& first, const LLSD& other) const;
  346. private:
  347. F64 mBlendedFactor;
  348. protected:
  349. LLAssetID mAssetID;
  350. LLSD mSettings;
  351. bool mIsValid;
  352. private:
  353. bool mDirty;
  354. bool mReplaced;
  355. };
  356. class LLSettingsBlender : public std::enable_shared_from_this<LLSettingsBlender>
  357. {
  358. protected:
  359. LOG_CLASS(LLSettingsBlender);
  360. public:
  361. typedef std::shared_ptr<LLSettingsBlender> ptr_t;
  362. typedef boost::signals2::signal<void(const ptr_t)> finish_signal_t;
  363. typedef boost::signals2::connection connection_t;
  364. LLSettingsBlender(const LLSettingsBase::ptr_t& target,
  365. const LLSettingsBase::ptr_t& initsetting,
  366. const LLSettingsBase::ptr_t& endsetting)
  367. : mOnFinished(),
  368. mTarget(target),
  369. mInitial(initsetting),
  370. mFinal(endsetting)
  371. {
  372. if (mInitial && mTarget)
  373. {
  374. mTarget->replaceSettings(mInitial->getSettings());
  375. }
  376. if (!mFinal)
  377. {
  378. mFinal = mInitial;
  379. }
  380. }
  381. virtual ~LLSettingsBlender() = default;
  382. virtual void reset(LLSettingsBase::ptr_t& initsetting,
  383. const LLSettingsBase::ptr_t& endsetting, F32);
  384. LL_INLINE LLSettingsBase::ptr_t getTarget() const { return mTarget; }
  385. LL_INLINE LLSettingsBase::ptr_t getInitial() const { return mInitial; }
  386. LL_INLINE LLSettingsBase::ptr_t getFinal() const { return mFinal; }
  387. LL_INLINE connection_t setOnFinished(const finish_signal_t::slot_type& sig)
  388. {
  389. return mOnFinished.connect(sig);
  390. }
  391. virtual void update(F64 blendf);
  392. LL_INLINE virtual bool applyTimeDelta(F64 delta) { return false; }
  393. virtual F64 setBlendFactor(F64 position);
  394. virtual void switchTrack(S32 trackno, F32 position) {}
  395. protected:
  396. void triggerComplete();
  397. protected:
  398. finish_signal_t mOnFinished;
  399. LLSettingsBase::ptr_t mTarget;
  400. LLSettingsBase::ptr_t mInitial;
  401. LLSettingsBase::ptr_t mFinal;
  402. };
  403. class LLSettingsBlenderTimeDelta : public LLSettingsBlender
  404. {
  405. protected:
  406. LOG_CLASS(LLSettingsBlenderTimeDelta);
  407. public:
  408. static constexpr F64 MIN_BLEND_DELTA = 0.001;
  409. LLSettingsBlenderTimeDelta(const LLSettingsBase::ptr_t& target,
  410. const LLSettingsBase::ptr_t& initsetting,
  411. const LLSettingsBase::ptr_t& endsetting,
  412. F64 blend_span)
  413. : LLSettingsBlender(target, initsetting, endsetting),
  414. mBlendSpan(blend_span),
  415. mLastUpdate(0.0),
  416. mTimeSpent(0.0),
  417. mBlendFMinDelta(MIN_BLEND_DELTA),
  418. mLastBlendF(-1.0)
  419. {
  420. mTimeStart = LLTimer::getEpochSeconds();
  421. mLastUpdate = mTimeStart;
  422. }
  423. LL_INLINE void reset(LLSettingsBase::ptr_t& initsetting,
  424. const LLSettingsBase::ptr_t& endsetting,
  425. F32 blend_span) override
  426. {
  427. LLSettingsBlender::reset(initsetting, endsetting, blend_span);
  428. mBlendSpan = blend_span;
  429. mTimeStart = LLTimer::getEpochSeconds();
  430. mLastUpdate = mTimeStart;
  431. mTimeSpent = 0.0;
  432. mLastBlendF = -1.0;
  433. }
  434. bool applyTimeDelta(F64 timedelta) override;
  435. LL_INLINE void setTimeSpent(F64 time) { mTimeSpent = time; }
  436. protected:
  437. F64 calculateBlend(F32 spanpos, F32 spanlen) const;
  438. protected:
  439. F64 mLastUpdate;
  440. F64 mTimeSpent;
  441. F64 mTimeStart;
  442. F64 mBlendFMinDelta;
  443. F64 mLastBlendF;
  444. F32 mBlendSpan;
  445. };
  446. #endif // LL_SETTINGSBASE_H