# Conflicts:
#	indra/newview/llspatialpartition.cpp
#	indra/newview/llvoavatar.cpp
#	indra/newview/llvovolume.cpp
This commit is contained in:
Shyotl
2019-04-11 02:02:05 -05:00
252 changed files with 10456 additions and 5211 deletions

View File

@@ -47,6 +47,40 @@
<key>version</key>
<string>1.2.15</string>
</map>
<key>abseil-cpp</key>
<map>
<key>canonical_repo</key>
<string>https://bitbucket.org/alchemyviewer/3p-abseil-src</string>
<key>copyright</key>
<string>Copyright 2018 The Abseil Authors.</string>
<key>description</key>
<string>Abseil Common Libraries</string>
<key>license</key>
<string>Apache 2.0</string>
<key>license_file</key>
<string>LICENSES/abseil-cpp.txt</string>
<key>name</key>
<string>abseil-cpp</string>
<key>platforms</key>
<map>
<key>common</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>b95e484e5b6cc0d10da48d3cf0ad37cd</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/packages/common/abseil_cpp-20190327.190862343-common-190862343.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
<string>20190327.190862343</string>
</map>
<key>apr_suite</key>
<map>
<key>copyright</key>
@@ -106,11 +140,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>76186b09770cab66dba6586cb1d2123f</string>
<string>d0cf074a2c95a65b8833350dad77c0ae</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/apr_suite-1.5.2-windows-201603261507.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/apr_suite-1.5.2-windows-201703090634.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -278,11 +312,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>d606e5c39d13f2c23d23ac498520cbac</string>
<string>ae0998e5d108c77c5cea2a68ad928151</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/boost-1.60.0-windows-201601152308.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/boost-1.63.0-windows-201703281813.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -362,11 +396,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>90a37cec15019bff53a165b90f0180a7</string>
<string>60bd2dbac5559141e05be6c424cf9cd0</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/colladadom-2.3-windows-201601152346.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/colladadom-2.3-windows-201703281922.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -448,11 +482,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f20491b59795d311cf8d730556cd141e</string>
<string>da5be630ca350a7ed4c0e99250451d41</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/curl-7.48.0-windows-201603231720.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/curl-7.56.1-windows-201711241310.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -551,6 +585,100 @@
<key>version</key>
<string>1</string>
</map>
<key>dullahan</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2017, Linden Research, Inc.</string>
<key>description</key>
<string>A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies.</string>
<key>license</key>
<string>MPL</string>
<key>license_file</key>
<string>LICENSES/LICENSE.txt</string>
<key>name</key>
<string>dullahan</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>118987b1a5b56214cfdbd0c763e180da</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15127/97748/dullahan-1.1.1080_3.3325.1750.gaabe4c4-darwin64-513449.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
<key>linux64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>2f44b376e436f37cbad5c7567edddebd</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://bitbucket.org/router_gray/rg_3p-dullahan/downloads/dullahan-1.1.1085-3.3497.1833.g13f506f-linux64-201902042123.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>2ecc71350b30a1057091b9cd7af18b1c</string>
<key>url</key>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc142/dullahan-1.1.930-3.3282.1733.g9091548-windows-201802202358.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
<key>windows64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>414190fd1ce3876ee3efc682b06ae65c</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/packages/windows64/msvc-1920/dullahan-1.1.1320_73.1.12-gee4b49f-chromium-73.0.3683.75-windows64-190871757.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.1.1320_73.1.12+gee4b49f+chromium-73.0.3683.75</string>
</map>
<key>elfio</key>
<map>
<key>license</key>
<string>lgpl</string>
<key>license_file</key>
<string>LICENSES/elfio.txt</string>
<key>name</key>
<string>elfio</string>
<key>platforms</key>
<map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>031e6315a5c0829c9b9a2ec18aeb7ae3</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-elfio/rev/222074/arch/Linux/installer/elfio-1.0.3-linux-20110225.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
</map>
</map>
</map>
<key>expat</key>
<map>
<key>copyright</key>
@@ -610,11 +738,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>454170939e4d1ba07060b73d6f81b9fc</string>
<string>f10218f7c28d63a3d9f1fb683d116bf8</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/expat-2.1.1-windows-201603261409.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/expat-2.2.0-windows-201703090626.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -698,11 +826,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>fe50f650c97e6350bedfd90102d3321f</string>
<string>b23a30967666da49346983658ed50e92</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://depot.alchemyviewer.org/pub/windows/lib/fmodstudio-1.08.04-windows-201605291158.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib/fmodstudio-1.10.00-windows-201709290225.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -769,6 +897,38 @@
<key>version</key>
<string>2.11.0</string>
</map>
<key>fonts</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2003 by Bitstream, Inc. Copyright (c) 2012 Adobe, Inc.</string>
<key>description</key>
<string>Font collection</string>
<key>license</key>
<string>Various</string>
<key>license_file</key>
<string>LICENSES/fonts.txt</string>
<key>name</key>
<string>fonts</string>
<key>platforms</key>
<map>
<key>common</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>b0172c35f6a8ac385c71604398966f80</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/packages/common/fonts-20190402.1-common-190922141.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
<string>20190402.1</string>
</map>
<key>freeglut</key>
<map>
<key>copyright</key>
@@ -874,11 +1034,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>e5be5197f12f9ca8078ba9ce4f1bce10</string>
<string>bdbfc3b58cfc2f125881be748d092645</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/freetype-2.6.3-windows-201603011805.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/freetype-2.8.0-windows-201710192344.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1024,11 +1184,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>05134ab3cf05fbfb4bed996b53a0d472</string>
<string>37035aad7d066dfe6f26dc009aa9dcea</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/glod-1.0pre4-windows-201601151027.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/glod-1.0pre4-windows-201703090622.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1110,11 +1270,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>19147e19b5cfaaaeb83ff1d9025c06df</string>
<string>fa7f683ba4ddd7db777c78c8213d2e46</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/google_breakpad-9e60a27-windows-201601151025.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/google_breakpad-7398ce15b79da-windows-201703090621.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1170,7 +1330,7 @@
<key>hash</key>
<string>e81d9e4526ceac49f1532d6518085985</string>
<key>url</key>
<string>https://bitbucket.org/alchemyviewer/publiclibs/downloads/gperftools-2.1-windows-20140120.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib/gperftools-2.1-windows-20140120.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1324,11 +1484,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>581db1bb70a7f6b9a6718121d22597a9</string>
<string>a9a7af50c5c1b5319dfea82cd09fdd84</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/jpeglib-1.4.2-windows-201601151022.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/jpeglib-1.5.1-windows-201703090615.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1410,11 +1570,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>440a81e502be320c789337653ad1af7c</string>
<string>cfce0b7d65b28b34fd0643cbcf7b0bac</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/libhunspell-1.3.3-windows-201601151018.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/libhunspell-1.6.0-windows-201703090619.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1516,11 +1676,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>1bed832715f068e3363ba90a0415092f</string>
<string>e2927116641e2c74ada092bfb6b49a8d</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/libndofdev-0.1-windows-201601151016.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/libndofdev-0.1-windows-201703090613.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1634,11 +1794,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>5e7b3ea13fec60f6c9a8965a390cfbd5</string>
<string>9aad0afaf2c1895224454c1dc433f481</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/libpng-1.6.21-windows-201603011800.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/libpng-1.6.34-windows-201710172201.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1720,11 +1880,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>6f1e3fcceab669df5c3d1c66821b2f24</string>
<string>a3f7c3421e9e4921dda3558c3b36dc59</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/libxml2-2.9.3-windows-201601151053.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/libxml2-2.9.4-windows-201703090740.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1747,80 +1907,6 @@
<key>version</key>
<string>2.9.3</string>
</map>
<key>llceflib</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2014-2015, Linden Research, Inc.</string>
<key>description</key>
<string>LLCefLib implements a headless web browser, rendering modern web content to a memory buffer and providing an API for injecting mouse and keyboard events. It uses the Chromium Embedded Framework (https://bitbucket.org/chromiumembedded/cef)</string>
<key>license</key>
<string>LGPL</string>
<key>license_file</key>
<string>LICENSES/llceflib.txt</string>
<key>name</key>
<string>llceflib</string>
<key>platforms</key>
<map>
<key>darwin</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>9551150830531abc405888066437e2c2</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://bitbucket.org/alchemyviewer/publiclibs-darwin/downloads/llceflib-3.2526.1364.gf6bf57b-darwin-201601160847.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
</map>
<key>linux64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>0e7613b2e038e18488452c2a9882144d</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/linux64/lib-trusty/llceflib-3.2526.1373.gb660893-linux64-201603281900.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>30bbc702d7533f8e2c56bdd0f5f22b59</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/llceflib-3.2526.1364.gf6bf57b-windows-201601160235.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
<key>windows64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>230e4ccb442bd538eabe2167f351a20d</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows64/lib-vc14/llceflib-3.2526.1364.gf6bf57b-windows64-201601160304.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>3.2526.1373.gb660893</string>
</map>
<key>llphysicsextensions_stub</key>
<map>
<key>copyright</key>
@@ -2062,11 +2148,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>e8c42c8ee03d570fa5e7fb88e7e1bc92</string>
<string>41d090321853ea941c5ca57ba0d471d0</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/ogg_vorbis-1.3.2-1.3.5-windows-201601151012.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/ogg_vorbis-1.3.2-1.3.5-windows-201703090612.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -2236,11 +2322,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>91b9fa570258f627a9265452d9e65231</string>
<string>0d25e1794f5d86b675484bf5eda799e4</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/openssl-1.0.2g-windows-201603011823.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/openssl-1.1.0g-windows-201711200028.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -2354,11 +2440,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>47a3316dae47cc4e7c1ea7b74ba8dd1e</string>
<string>5a78539626b5f23522d0b466247f48b4</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/vivox_3p-slvoice/rev/302004/arch/CYGWIN/installer/slvoice-4.6.0017.22050.302004-windows-302004.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21422/157291/slvoice-4.9.0002.30313.517593-windows-517593.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -2590,11 +2676,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>7a619778a2ea5c3113549529dd4f7288</string>
<string>4cd5d80362fef95fe486b5bc1c373174</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/xmlrpc_epi-0.54.2-windows-201603261505.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/xmlrpc_epi-0.54.2-windows-201703090632.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -2676,11 +2762,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>a26a7a9d550dc6988528e2e70bb5e85b</string>
<string>75651f8b2fa45545461f73ba583180bb</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/windows/lib-vc14/zlib-1.2.8-windows-201601150945.tar.bz2</string>
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/zlib-1.2.11-windows-201703090604.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>

View File

@@ -108,7 +108,7 @@ if (WINDOWS)
endif (USE_LTO)
if (WORD_SIZE EQUAL 32)
add_compile_options(/arch:SSE3)
add_compile_options(/arch:SSE2)
endif (WORD_SIZE EQUAL 32)
if (NOT DISABLE_FATAL_WARNINGS)

View File

@@ -46,6 +46,7 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
set(VIEWER_CHANNEL_VERSION_DEFINES
"LL_VIEWER_CHANNEL=\"${VIEWER_CHANNEL}\""
"LL_VIEWER_CHANNEL_GRK=\"${VIEWER_CHANNEL_GRK}\""
"LL_VIEWER_VERSION_MAJOR=${VIEWER_VERSION_MAJOR}"
"LL_VIEWER_VERSION_MINOR=${VIEWER_VERSION_MINOR}"
"LL_VIEWER_VERSION_PATCH=${VIEWER_VERSION_PATCH}"

View File

@@ -6,7 +6,7 @@ if (USESYSTEMLIBS)
set(CEFPLUGIN OFF CACHE BOOL
"CEFPLUGIN support for the llplugin/llmedia test apps.")
else (USESYSTEMLIBS)
use_prebuilt_binary(llceflib)
use_prebuilt_binary(dullahan)
set(CEFPLUGIN ON CACHE BOOL
"CEFPLUGIN support for the llplugin/llmedia test apps.")
set(CEF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/cef)
@@ -16,7 +16,7 @@ if (WINDOWS)
set(CEF_PLUGIN_LIBRARIES
libcef.lib
libcef_dll_wrapper.lib
llceflib.lib
dullahan.lib
)
elseif (DARWIN)
FIND_LIBRARY(APPKIT_LIBRARY AppKit)
@@ -31,14 +31,14 @@ elseif (DARWIN)
set(CEF_PLUGIN_LIBRARIES
${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
${ARCH_PREBUILT_DIRS_RELEASE}/libLLCefLib.a
${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a
${APPKIT_LIBRARY}
${CEF_LIBRARY}
)
elseif (LINUX)
set(CEF_PLUGIN_LIBRARIES
llceflib
dullahan
cef_dll_wrapper
cef
)

View File

@@ -20,11 +20,9 @@ if(WINDOWS)
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(vivox_files
SLVoice.exe
ca-bundle.crt
libsndfile-1.dll
vivoxsdk.dll
ortp.dll
vivoxoal.dll
vivoxplatform.dll
)
#*******************************

View File

@@ -9,9 +9,7 @@
# LINUX - Linux
# WINDOWS - Windows
# Relative and absolute paths to subtrees.
if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
@@ -24,13 +22,36 @@ set(LIBS_OPEN_PREFIX)
set(SCRIPTS_PREFIX ../scripts)
set(VIEWER_PREFIX)
set(INTEGRATION_TESTS_PREFIX)
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)")
option(LL_TESTS "Build and run unit and integration tests (disable for build timing runs to reduce variation" OFF)
# Compiler and toolchain options
option(USESYSTEMLIBS "Use libraries from your system rather than Linden-supplied prebuilt libraries." OFF)
option(STANDALONE "Use libraries from your system rather than Linden-supplied prebuilt libraries." OFF)
if (USESYSTEMLIBS)
set(STANDALONE ON)
elseif (STANDALONE)
set(USESYSTEMLIBS ON)
endif (USESYSTEMLIBS)
option(INCREMENTAL_LINK "Use incremental linking on win32 builds (enable for faster links on some machines)" OFF)
option(USE_PRECOMPILED_HEADERS "Enable use of precompiled header directives where supported." ON)
option(USE_LTO "Enable Whole Program Optimization and related folding and binary reduction routines" OFF)
option(UNATTENDED "Disable use of uneeded tooling for automated builds" OFF)
# Media Plugins
option(ENABLE_MEDIA_PLUGINS "Turn off building media plugins if they are imported by third-party library mechanism" ON)
option(LIBVLCPLUGIN "Turn off building support for libvlc plugin" ON)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(LIBVLCPLUGIN OFF)
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Mallocs
set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)")
set(DISABLE_FATAL_WARNINGS TRUE CACHE BOOL "Set this to FALSE to enable fatal warnings.")
option(INCREMENTAL_LINK "Use incremental linking or incremental LTCG for LTO on win32 builds (enable for faster links on some machines)" OFF)
option(USE_LTO "Enable Whole Program Optimization and related folding and binary reduction routines" OFF)
# Audio Engines
option(FMODSTUDIO "Build with support for the FMOD Studio audio engine" OFF)
# Window implementation
option(LLWINDOW_SDL2 "Use SDL2 for window and input handling" OFF)
# Proprietary Library Features
option(NVAPI "Use nvapi driver interface library" OFF)
@@ -60,13 +81,14 @@ if (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)
set(INSTALL_PROPRIETARY ON CACHE BOOL "Install proprietary binaries")
endif (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)
set(TEMPLATE_VERIFIER_OPTIONS "" CACHE STRING "Options for scripts/template_verifier.py")
set(TEMPLATE_VERIFIER_MASTER_URL "http://bitbucket.org/lindenlab/master-message-template/raw/tip/message_template.msg" CACHE STRING "Location of the master message template")
set(TEMPLATE_VERIFIER_MASTER_URL "https://forge.alchemyviewer.org/alchemy/tools/Master-Message-Template/raw/master/message_template.msg" CACHE STRING "Location of the master message template")
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Build type. One of: Debug Release RelWithDebInfo" FORCE)
endif (NOT CMAKE_BUILD_TYPE)
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(WINDOWS ON BOOL FORCE)
if (WORD_SIZE EQUAL 64)
@@ -142,63 +164,94 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(DARWIN 1)
execute_process(
COMMAND sh -c "xcodebuild -version | grep Xcode | cut -d ' ' -f2 | cut -d'.' -f1-2"
OUTPUT_VARIABLE XCODE_VERSION )
string(REGEX REPLACE "(\r?\n)+$" "" XCODE_VERSION "${XCODE_VERSION}")
if (XCODE_VERSION LESS 8.0.0)
message( FATAL_ERROR "Xcode 8.0.0 or greater is required." )
endif (XCODE_VERSION LESS 8.0.0)
message( "Building with " ${CMAKE_OSX_SYSROOT} )
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12)
# Hardcode SDK we build against until we can test and allow newer ones
# as autodetected in the code above
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
set(CMAKE_OSX_SYSROOT macosx10.6)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL 3)
set(CMAKE_XCODE_ATTRIBUTE_GCC_STRICT_ALIASING NO)
set(CMAKE_XCODE_ATTRIBUTE_GCC_FAST_MATH NO)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14")
if (USE_AVX2)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS avx2)
elseif (USE_AVX)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS avx)
else ()
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS sse4.1)
endif ()
# Support for Unix Makefiles generator
if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
execute_process(COMMAND xcodebuild -version -sdk "${CMAKE_OSX_SYSROOT}" Path | head -n 1 OUTPUT_VARIABLE CMAKE_OSX_SYSROOT)
string(REGEX REPLACE "(\r?\n)+$" "" CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT}")
endif (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
# LLVM-GCC has been removed in Xcode5
if (XCODE_VERSION GREATER 4.9)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
else (XCODE_VERSION GREATER 4.9)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
endif (XCODE_VERSION GREATER 4.9)
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
else (${CMAKE_BUILD_TYPE} STREQUAL "Release")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf)
endif (${CMAKE_BUILD_TYPE} STREQUAL "Release")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
message(STATUS "Xcode version: ${XCODE_VERSION}")
message(STATUS "OSX sysroot: ${CMAKE_OSX_SYSROOT}")
message(STATUS "OSX deployment target: ${CMAKE_OSX_DEPLOYMENT_TARGET}")
# Build only for i386 by default, system default on MacOSX 10.6 is x86_64
set(CMAKE_OSX_ARCHITECTURES i386)
set(ARCH i386)
set(WORD_SIZE 32)
set(AUTOBUILD_PLATFORM_NAME "darwin")
set(ADDRESS_SIZE 64)
if (NOT CMAKE_OSX_ARCHITECTURES)
if (ADDRESS_SIZE EQUAL 64)
set(CMAKE_OSX_ARCHITECTURES x86_64)
else (ADDRESS_SIZE EQUAL 64)
set(CMAKE_OSX_ARCHITECTURES i386)
endif (ADDRESS_SIZE EQUAL 64)
endif (NOT CMAKE_OSX_ARCHITECTURES)
if (ADDRESS_SIZE EQUAL 64)
set(ARCH x86_64)
else (ADDRESS_SIZE EQUAL 64)
set(ARCH i386)
endif (ADDRESS_SIZE EQUAL 64)
set(LL_ARCH ${ARCH}_darwin)
set(LL_ARCH_DIR universal-darwin)
set(AUTOBUILD_PLATFORM_NAME "darwin" CACHE STRING "Autobuild Platform Name")
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Default deploy grid
set(GRID agni CACHE STRING "Target Grid")
set(VIEWER_CHANNEL "Singularity Test" CACHE STRING "Viewer Channel Name")
set(VIEWER_PRODUCT_NAME "Singularity" CACHE STRING "Viewer Base Name")
string(TOLOWER ${VIEWER_PRODUCT_NAME} VIEWER_PRODUCT_NAME_LOWER)
string(REPLACE " " "" VIEWER_CHANNEL_NOSPACE ${VIEWER_CHANNEL})
set(VIEWER_CHANNEL_NOSPACE ${VIEWER_CHANNEL_NOSPACE} CACHE STRING "Prefix used for resulting artifacts.")
set(VIEWER_CHANNEL_BASE "Test" CACHE STRING "Viewer Channel Name")
set(VIEWER_CHANNEL "${VIEWER_PRODUCT_NAME} ${VIEWER_CHANNEL_BASE}")
string(TOLOWER ${VIEWER_CHANNEL} VIEWER_CHANNEL_LOWER)
string(REPLACE " " "" VIEWER_CHANNEL_ONEWORD ${VIEWER_CHANNEL})
option(VIEWER_CHANNEL_GRK "Greek character(s) to represent the viewer channel for support purposes, override only for special branches" "")
if (NOT VIEWER_CHANNEL_GRK)
if (VIEWER_CHANNEL_BASE MATCHES "Test")
set(VIEWER_CHANNEL_GRK "τ")
elseif (VIEWER_CHANNEL_BASE MATCHES "Alpha")
set(VIEWER_CHANNEL_GRK "α")
elseif (VIEWER_CHANNEL_BASE MATCHES "Beta")
set(VIEWER_CHANNEL_GRK "β")
endif ()
endif (NOT VIEWER_CHANNEL_GRK)
if(VIEWER_CHANNEL_LOWER MATCHES "^${VIEWER_PRODUCT_NAME_LOWER} release")
set(VIEWER_PACKAGE_ID "${VIEWER_PRODUCT_NAME}Release")
set(VIEWER_EXE_STRING "${VIEWER_PRODUCT_NAME}Viewer")
set(VIEWER_SHORTCUT_STRING "${VIEWER_PRODUCT_NAME} Viewer")
else()
set(VIEWER_PACKAGE_ID ${VIEWER_CHANNEL_ONEWORD})
set(VIEWER_EXE_STRING ${VIEWER_CHANNEL_ONEWORD})
set(VIEWER_SHORTCUT_STRING ${VIEWER_CHANNEL})
endif()
set(VIEWER_CHANNEL_NOSPACE ${VIEWER_CHANNEL_ONEWORD} CACHE STRING "Prefix used for resulting artifacts.")
set(VIEWER_BRANDING_ID "singularity" CACHE STRING "Viewer branding id")
set(ENABLE_SIGNING OFF CACHE BOOL "Enable signing the viewer")
set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.")
set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")
set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
option(ENABLE_SIGNING "Enable signing the viewer" OFF)
set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.")
source_group("CMake Rules" FILES CMakeLists.txt)
mark_as_advanced(AUTOBUILD_PLATFORM_NAME)
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)

View File

@@ -15,3 +15,5 @@ else (NOT STANDALONE)
endif(LINUX AND ${ARCH} STREQUAL "x86_64")
set(STANDALONE ON)
endif(NOT STANDALONE)
use_prebuilt_binary(fonts)

View File

@@ -29,17 +29,17 @@
#include "llinventorytype.h"
#include "llinventorydefines.h"
static LLTranslationBridge* sTrans = NULL;
static LLTranslationBridge::ptr_t sTrans = NULL;
// static
void LLWearableType::initClass(LLTranslationBridge* trans)
void LLWearableType::initClass(LLTranslationBridge::ptr_t &trans)
{
sTrans = trans;
}
void LLWearableType::cleanupClass()
{
delete sTrans;
sTrans.reset();
}
struct WearableEntry : public LLDictionaryEntry
@@ -53,8 +53,7 @@ struct WearableEntry : public LLDictionaryEntry
LLDictionaryEntry(name),
mAssetType(assetType),
mDefaultNewName(default_new_name),
//*TODO:Translate
mLabel(/*sTrans->getString*/(name)),
mLabel(sTrans->getString(name)),
mIconName(iconName),
mDisableCameraSwitch(disable_camera_switch),
mAllowMultiwear(allow_multiwear)
@@ -184,6 +183,6 @@ BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type)
// static
LLWearableType::EType LLWearableType::inventoryFlagsToWearableType(U32 flags)
{
return (LLWearableType::EType)(flags & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);
return (LLWearableType::EType)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
}

View File

@@ -31,16 +31,7 @@
#include "lldictionary.h"
#include "llinventorytype.h"
#include "llsingleton.h"
class LLTranslationBridge
{
public:
// clang needs this to be happy
virtual ~LLTranslationBridge() {}
virtual std::string getString(const std::string &xml_desc) = 0;
};
#include "llinvtranslationbrdg.h"
class LLWearableType
{
@@ -72,7 +63,7 @@ public:
WT_NONE = -1,
};
static void initClass(LLTranslationBridge* trans); // initializes static members
static void initClass(LLTranslationBridge::ptr_t &trans); // initializes static members
static void cleanupClass(); // initializes static members
static const std::string& getTypeName(EType type);

View File

@@ -200,7 +200,7 @@ void LLMotionController::purgeExcessMotions()
}
//</singu>
std::set<LLUUID> motions_to_kill;
uuid_set_t motions_to_kill;
if (1) // Singu: leave indentation alone...
{
@@ -220,7 +220,7 @@ void LLMotionController::purgeExcessMotions()
}
// clean up all inactive, loaded motions
for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin();
for (auto motion_it = motions_to_kill.begin();
motion_it != motions_to_kill.end();
++motion_it)
{

View File

@@ -36,7 +36,7 @@
#include "lldatapacker.h"
#include "llstl.h"
const S32 GESTURE_VERSION = 2;
constexpr S32 GESTURE_VERSION = 2;
//---------------------------------------------------------------------------
// LLMultiGesture
@@ -48,10 +48,10 @@ LLMultiGesture::LLMultiGesture()
mTrigger(),
mReplaceText(),
mSteps(),
mPlaying(FALSE),
mPlaying(false),
mLocal(false),
mCurrentStep(0),
mDoneCallback(NULL)
mDoneCallback(nullptr)
{
reset();
}
@@ -63,13 +63,13 @@ LLMultiGesture::~LLMultiGesture()
void LLMultiGesture::reset()
{
mPlaying = FALSE;
mPlaying = false;
mLocal = false;
mCurrentStep = 0;
mWaitTimer.reset();
mWaitingTimer = FALSE;
mWaitingAnimations = FALSE;
mWaitingAtEnd = FALSE;
mWaitingTimer = false;
mWaitingAnimations = false;
mWaitingAtEnd = false;
mRequestedAnimIDs.clear();
mPlayingAnimIDs.clear();
}
@@ -88,10 +88,8 @@ S32 LLMultiGesture::getMaxSerialSize() const
max_size += 64; // step count S32
std::vector<LLGestureStep*>::const_iterator it;
for (it = mSteps.begin(); it != mSteps.end(); ++it)
for (const auto& step : mSteps)
{
LLGestureStep* step = *it;
max_size += 64; // type S32
max_size += step->getMaxSerialSize();
}
@@ -104,10 +102,8 @@ S32 LLMultiGesture::getMaxSerialSize() const
max_size += sizeof(S32); // step count
std::vector<LLGestureStep*>::const_iterator it;
for (it = mSteps.begin(); it != mSteps.end(); ++it)
for (const auto& step : mSteps)
{
LLGestureStep* step = *it;
max_size += sizeof(S32); // type
max_size += step->getMaxSerialSize();
}
@@ -116,7 +112,7 @@ S32 LLMultiGesture::getMaxSerialSize() const
return max_size;
}
BOOL LLMultiGesture::serialize(LLDataPacker& dp) const
bool LLMultiGesture::serialize(LLDataPacker& dp) const
{
dp.packS32(GESTURE_VERSION, "version");
dp.packU8(mKey, "key");
@@ -126,22 +122,18 @@ BOOL LLMultiGesture::serialize(LLDataPacker& dp) const
S32 count = (S32)mSteps.size();
dp.packS32(count, "step_count");
S32 i;
for (i = 0; i < count; ++i)
for (const auto& step : mSteps)
{
LLGestureStep* step = mSteps[i];
dp.packS32(step->getType(), "step_type");
BOOL ok = step->serialize(dp);
if (!ok)
if (!step->serialize(dp))
{
return FALSE;
return false;
}
}
return TRUE;
return true;
}
BOOL LLMultiGesture::deserialize(LLDataPacker& dp)
bool LLMultiGesture::deserialize(LLDataPacker& dp)
{
S32 version;
dp.unpackS32(version, "version");
@@ -150,15 +142,12 @@ BOOL LLMultiGesture::deserialize(LLDataPacker& dp)
LL_WARNS() << "Bad LLMultiGesture version " << version
<< " should be " << GESTURE_VERSION
<< LL_ENDL;
return FALSE;
return false;
}
dp.unpackU8(mKey, "key");
dp.unpackU32(mMask, "mask");
dp.unpackString(mTrigger, "trigger");
dp.unpackString(mReplaceText, "replace");
S32 count;
@@ -166,58 +155,31 @@ BOOL LLMultiGesture::deserialize(LLDataPacker& dp)
if (count < 0)
{
LL_WARNS() << "Bad LLMultiGesture step count " << count << LL_ENDL;
return FALSE;
return false;
}
S32 i;
for (i = 0; i < count; ++i)
std::unique_ptr<LLGestureStep> step;
for (S32 i = 0; i < count; ++i)
{
S32 type;
dp.unpackS32(type, "step_type");
EStepType step_type = (EStepType)type;
switch(step_type)
switch((EStepType)type)
{
case STEP_ANIMATION:
{
std::unique_ptr<LLGestureStep> step(new LLGestureStepAnimation());
BOOL ok = step->deserialize(dp);
if (!ok) return FALSE;
mSteps.push_back(step.release());
break;
}
case STEP_SOUND:
{
std::unique_ptr<LLGestureStep> step(new LLGestureStepSound());
BOOL ok = step->deserialize(dp);
if (!ok) return FALSE;
mSteps.push_back(step.release());
break;
}
case STEP_CHAT:
{
std::unique_ptr<LLGestureStep> step(new LLGestureStepChat());
BOOL ok = step->deserialize(dp);
if (!ok) return FALSE;
mSteps.push_back(step.release());
break;
}
case STEP_WAIT:
{
std::unique_ptr<LLGestureStep> step(new LLGestureStepWait());
BOOL ok = step->deserialize(dp);
if (!ok) return FALSE;
mSteps.push_back(step.release());
break;
}
case STEP_ANIMATION: step.reset(new LLGestureStepAnimation); break;
case STEP_SOUND: step.reset(new LLGestureStepSound); break;
case STEP_CHAT: step.reset(new LLGestureStepChat); break;
case STEP_WAIT: step.reset(new LLGestureStepWait); break;
default:
{
LL_WARNS() << "Bad LLMultiGesture step type " << type << LL_ENDL;
return FALSE;
return false;
}
}
if (!step->deserialize(dp)) return false;
mSteps.push_back(step.release());
}
return TRUE;
return true;
}
void LLMultiGesture::dump()
@@ -226,10 +188,8 @@ void LLMultiGesture::dump()
<< " trigger " << mTrigger
<< " replace " << mReplaceText
<< LL_ENDL;
U32 i;
for (i = 0; i < mSteps.size(); ++i)
for (const auto& step : mSteps)
{
LLGestureStep* step = mSteps[i];
step->dump();
}
}
@@ -264,21 +224,21 @@ S32 LLGestureStepAnimation::getMaxSerialSize() const
return max_size;
}
BOOL LLGestureStepAnimation::serialize(LLDataPacker& dp) const
bool LLGestureStepAnimation::serialize(LLDataPacker& dp) const
{
dp.packString(mAnimName, "anim_name");
dp.packUUID(mAnimAssetID, "asset_id");
dp.packU32(mFlags, "flags");
return TRUE;
return true;
}
BOOL LLGestureStepAnimation::deserialize(LLDataPacker& dp)
bool LLGestureStepAnimation::deserialize(LLDataPacker& dp)
{
dp.unpackString(mAnimName, "anim_name");
// Apparently an earlier version of the gesture code added \r to the end
// of the animation names. Get rid of it. JC
if (!mAnimName.empty() && mAnimName[mAnimName.length() - 1] == '\r')
if (!mAnimName.empty() && mAnimName.back() == '\r')
{
// chop the last character
mAnimName.resize(mAnimName.length() - 1);
@@ -286,29 +246,18 @@ BOOL LLGestureStepAnimation::deserialize(LLDataPacker& dp)
dp.unpackUUID(mAnimAssetID, "asset_id");
dp.unpackU32(mFlags, "flags");
return TRUE;
return true;
}
// *NOTE: result is translated in LLPreviewGesture::getLabel()
std::vector<std::string> LLGestureStepAnimation::getLabel() const
{
std::vector<std::string> strings;
// std::string label;
/* std::string label;
if (mFlags & ANIM_FLAG_STOP)
{
strings.push_back( "AnimFlagStop");
// label = "Stop Animation: ";
}
label = "Stop Animation: ";
else
{
strings.push_back( "AnimFlagStart");
// label = "Start Animation: ";
}
strings.push_back( mAnimName);
// label += mAnimName;
return strings;
label = "Start Animation: ";
label += mAnimName;*/
return {mFlags & ANIM_FLAG_STOP ? "AnimFlagStop" : "AnimFlagStart", mAnimName};
}
void LLGestureStepAnimation::dump()
@@ -346,31 +295,28 @@ S32 LLGestureStepSound::getMaxSerialSize() const
return max_size;
}
BOOL LLGestureStepSound::serialize(LLDataPacker& dp) const
bool LLGestureStepSound::serialize(LLDataPacker& dp) const
{
dp.packString(mSoundName, "sound_name");
dp.packUUID(mSoundAssetID, "asset_id");
dp.packU32(mFlags, "flags");
return TRUE;
return true;
}
BOOL LLGestureStepSound::deserialize(LLDataPacker& dp)
bool LLGestureStepSound::deserialize(LLDataPacker& dp)
{
dp.unpackString(mSoundName, "sound_name");
dp.unpackUUID(mSoundAssetID, "asset_id");
dp.unpackU32(mFlags, "flags");
return TRUE;
return true;
}
// *NOTE: result is translated in LLPreviewGesture::getLabel()
std::vector<std::string> LLGestureStepSound::getLabel() const
{
std::vector<std::string> strings;
strings.push_back( "Sound");
strings.push_back( mSoundName);
// std::string label("Sound: ");
// label += mSoundName;
return strings;
return {"Sound", mSoundName};
}
void LLGestureStepSound::dump()
@@ -406,27 +352,23 @@ S32 LLGestureStepChat::getMaxSerialSize() const
return max_size;
}
BOOL LLGestureStepChat::serialize(LLDataPacker& dp) const
bool LLGestureStepChat::serialize(LLDataPacker& dp) const
{
dp.packString(mChatText, "chat_text");
dp.packU32(mFlags, "flags");
return TRUE;
return true;
}
BOOL LLGestureStepChat::deserialize(LLDataPacker& dp)
bool LLGestureStepChat::deserialize(LLDataPacker& dp)
{
dp.unpackString(mChatText, "chat_text");
dp.unpackU32(mFlags, "flags");
return TRUE;
return true;
}
// *NOTE: result is translated in LLPreviewGesture::getLabel()
std::vector<std::string> LLGestureStepChat::getLabel() const
{
std::vector<std::string> strings;
strings.push_back("Chat");
strings.push_back(mChatText);
return strings;
return {"Chat", mChatText};
}
void LLGestureStepChat::dump()
@@ -461,44 +403,26 @@ S32 LLGestureStepWait::getMaxSerialSize() const
return max_size;
}
BOOL LLGestureStepWait::serialize(LLDataPacker& dp) const
bool LLGestureStepWait::serialize(LLDataPacker& dp) const
{
dp.packF32(mWaitSeconds, "wait_seconds");
dp.packU32(mFlags, "flags");
return TRUE;
return true;
}
BOOL LLGestureStepWait::deserialize(LLDataPacker& dp)
bool LLGestureStepWait::deserialize(LLDataPacker& dp)
{
dp.unpackF32(mWaitSeconds, "wait_seconds");
dp.unpackU32(mFlags, "flags");
return TRUE;
return true;
}
// *NOTE: result is translated in LLPreviewGesture::getLabel()
std::vector<std::string> LLGestureStepWait::getLabel() const
{
std::vector<std::string> strings;
strings.push_back( "Wait" );
// std::string label("--- Wait: ");
if (mFlags & WAIT_FLAG_TIME)
{
char buffer[64]; /* Flawfinder: ignore */
snprintf(buffer, sizeof(buffer), "%.1f seconds", (double)mWaitSeconds); /* Flawfinder: ignore */
strings.push_back(buffer);
// label += buffer;
}
else if (mFlags & WAIT_FLAG_ALL_ANIM)
{
strings.push_back("until animations are done");
// label += "until animations are done";
}
else
{
strings.push_back("");
}
return strings;
return {"Wait",
mFlags & WAIT_FLAG_TIME ? llformat("%.1f seconds", mWaitSeconds)
: mFlags & WAIT_FLAG_ALL_ANIM ? "until animations are done"
: LLStringUtil::null};
}

View File

@@ -27,7 +27,7 @@
#ifndef LL_LLMULTIGESTURE_H
#define LL_LLMULTIGESTURE_H
#include <set>
#include <boost/unordered_set.hpp>
#include <string>
#include <vector>
@@ -46,8 +46,8 @@ public:
// Maximum number of bytes this could hold once serialized.
S32 getMaxSerialSize() const;
BOOL serialize(LLDataPacker& dp) const;
BOOL deserialize(LLDataPacker& dp);
bool serialize(LLDataPacker& dp) const;
bool deserialize(LLDataPacker& dp);
void dump();
@@ -77,7 +77,7 @@ public:
std::vector<LLGestureStep*> mSteps;
// Is the gesture currently playing?
BOOL mPlaying;
bool mPlaying;
// Is the gesture to be played locally?
bool mLocal;
@@ -86,25 +86,25 @@ public:
S32 mCurrentStep;
// We're waiting for triggered animations to stop playing
BOOL mWaitingAnimations;
bool mWaitingAnimations;
// We're waiting a fixed amount of time
BOOL mWaitingTimer;
bool mWaitingTimer;
// Waiting after the last step played for all animations to complete
BOOL mWaitingAtEnd;
bool mWaitingAtEnd;
// Timer for waiting
LLFrameTimer mWaitTimer;
boost::function<void (LLMultiGesture*)> mDoneCallback;
std::function<void (LLMultiGesture*)> mDoneCallback;
// Animations that we requested to start
std::set<LLUUID> mRequestedAnimIDs;
uuid_set_t mRequestedAnimIDs;
// Once the animation starts playing (sim says to start playing)
// the ID is moved from mRequestedAnimIDs to here.
std::set<LLUUID> mPlayingAnimIDs;
uuid_set_t mPlayingAnimIDs;
};
@@ -127,14 +127,14 @@ public:
LLGestureStep() {}
virtual ~LLGestureStep() {}
virtual EStepType getType() = 0;
virtual EStepType getType() const = 0;
// Return a user-readable label for this step
virtual std::vector<std::string> getLabel() const = 0;
virtual S32 getMaxSerialSize() const = 0;
virtual BOOL serialize(LLDataPacker& dp) const = 0;
virtual BOOL deserialize(LLDataPacker& dp) = 0;
virtual bool serialize(LLDataPacker& dp) const = 0;
virtual bool deserialize(LLDataPacker& dp) = 0;
virtual void dump() = 0;
};
@@ -142,7 +142,7 @@ public:
// By default, animation steps start animations.
// If the least significant bit is 1, it will stop animations.
const U32 ANIM_FLAG_STOP = 0x01;
constexpr U32 ANIM_FLAG_STOP = 0x01;
class LLGestureStepAnimation : public LLGestureStep
{
@@ -150,15 +150,15 @@ public:
LLGestureStepAnimation();
virtual ~LLGestureStepAnimation();
virtual EStepType getType() { return STEP_ANIMATION; }
EStepType getType() const override { return STEP_ANIMATION; }
virtual std::vector<std::string> getLabel() const;
std::vector<std::string> getLabel() const override;
virtual S32 getMaxSerialSize() const;
virtual BOOL serialize(LLDataPacker& dp) const;
virtual BOOL deserialize(LLDataPacker& dp);
S32 getMaxSerialSize() const override;
bool serialize(LLDataPacker& dp) const override;
bool deserialize(LLDataPacker& dp) override;
virtual void dump();
void dump() override;
public:
std::string mAnimName;
@@ -173,15 +173,15 @@ public:
LLGestureStepSound();
virtual ~LLGestureStepSound();
virtual EStepType getType() { return STEP_SOUND; }
EStepType getType() const override { return STEP_SOUND; }
virtual std::vector<std::string> getLabel() const;
std::vector<std::string> getLabel() const override;
virtual S32 getMaxSerialSize() const;
virtual BOOL serialize(LLDataPacker& dp) const;
virtual BOOL deserialize(LLDataPacker& dp);
S32 getMaxSerialSize() const override;
bool serialize(LLDataPacker& dp) const override;
bool deserialize(LLDataPacker& dp) override;
virtual void dump();
void dump() override;
public:
std::string mSoundName;
@@ -196,15 +196,15 @@ public:
LLGestureStepChat();
virtual ~LLGestureStepChat();
virtual EStepType getType() { return STEP_CHAT; }
EStepType getType() const override { return STEP_CHAT; }
virtual std::vector<std::string> getLabel() const;
std::vector<std::string> getLabel() const override;
virtual S32 getMaxSerialSize() const;
virtual BOOL serialize(LLDataPacker& dp) const;
virtual BOOL deserialize(LLDataPacker& dp);
S32 getMaxSerialSize() const override;
bool serialize(LLDataPacker& dp) const override;
bool deserialize(LLDataPacker& dp) override;
virtual void dump();
void dump() override;
public:
std::string mChatText;
@@ -212,8 +212,8 @@ public:
};
const U32 WAIT_FLAG_TIME = 0x01;
const U32 WAIT_FLAG_ALL_ANIM = 0x02;
constexpr U32 WAIT_FLAG_TIME = 0x01;
constexpr U32 WAIT_FLAG_ALL_ANIM = 0x02;
class LLGestureStepWait : public LLGestureStep
{
@@ -221,15 +221,15 @@ public:
LLGestureStepWait();
virtual ~LLGestureStepWait();
virtual EStepType getType() { return STEP_WAIT; }
EStepType getType() const override { return STEP_WAIT; }
virtual std::vector<std::string> getLabel() const;
std::vector<std::string> getLabel() const override;
virtual S32 getMaxSerialSize() const;
virtual BOOL serialize(LLDataPacker& dp) const;
virtual BOOL deserialize(LLDataPacker& dp);
S32 getMaxSerialSize() const override;
bool serialize(LLDataPacker& dp) const override;
bool deserialize(LLDataPacker& dp) override;
virtual void dump();
void dump() override;
public:
F32 mWaitSeconds;

View File

@@ -131,6 +131,7 @@ public:
virtual bool has(const String&) const { return false; }
virtual LLSD get(const String&) const { return LLSD(); }
virtual LLSD getKeys() const { return LLSD::emptyArray(); }
virtual void erase(const String&) { }
virtual const LLSD& ref(const String&) const{ return undef(); }
@@ -379,6 +380,7 @@ namespace
using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer)
using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer)
virtual LLSD get(const LLSD::String&) const;
virtual LLSD getKeys() const;
void insert(const LLSD::String& k, const LLSD& v);
virtual void erase(const LLSD::String&);
LLSD& ref(const LLSD::String&);
@@ -421,6 +423,18 @@ namespace
return (i != mData.end()) ? i->second : LLSD();
}
LLSD ImplMap::getKeys() const
{
LLSD keys = LLSD::emptyArray();
DataMap::const_iterator iter = mData.begin();
while (iter != mData.end())
{
keys.append((*iter).first);
iter++;
}
return keys;
}
void ImplMap::insert(const LLSD::String& k, const LLSD& v)
{
mData.insert(DataMap::value_type(k, v));
@@ -501,7 +515,7 @@ namespace
virtual LLSD get(LLSD::Integer) const;
void set(LLSD::Integer, const LLSD&);
void insert(LLSD::Integer, const LLSD&);
void append(const LLSD&);
LLSD& append(const LLSD&);
virtual void erase(LLSD::Integer);
LLSD& ref(LLSD::Integer);
virtual const LLSD& ref(LLSD::Integer) const;
@@ -569,9 +583,10 @@ namespace
mData.insert(mData.begin() + index, v);
}
void ImplArray::append(const LLSD& v)
LLSD& ImplArray::append(const LLSD& v)
{
mData.push_back(v);
return mData.back();
}
void ImplArray::erase(LLSD::Integer i)
@@ -862,6 +877,7 @@ LLSD LLSD::emptyMap()
bool LLSD::has(const String& k) const { return safe(impl).has(k); }
LLSD LLSD::get(const String& k) const { return safe(impl).get(k); }
LLSD LLSD::getKeys() const { return safe(impl).getKeys(); }
void LLSD::insert(const String& k, const LLSD& v) { makeMap(impl).insert(k, v); }
LLSD& LLSD::with(const String& k, const LLSD& v)
@@ -895,7 +911,7 @@ LLSD& LLSD::with(Integer i, const LLSD& v)
makeArray(impl).insert(i, v);
return *this;
}
void LLSD::append(const LLSD& v) { makeArray(impl).append(v); }
LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); }
void LLSD::erase(Integer i) { makeArray(impl).erase(i); }
LLSD& LLSD::operator[](Integer i)

View File

@@ -287,6 +287,7 @@ public:
bool has(const String&) const;
LLSD get(const String&) const;
LLSD getKeys() const; // Return an LLSD array with keys as strings
void insert(const String&, const LLSD&);
void erase(const String&);
LLSD& with(const String&, const LLSD&);
@@ -304,7 +305,7 @@ public:
LLSD get(Integer) const;
void set(Integer, const LLSD&);
void insert(Integer, const LLSD&);
void append(const LLSD&);
LLSD& append(const LLSD&);
void erase(Integer);
LLSD& with(Integer, const LLSD&);

View File

@@ -55,6 +55,7 @@ static const int MAX_HDR_LEN = 20;
static const char LEGACY_NON_HEADER[] = "<llsd>";
const std::string LLSD_BINARY_HEADER("LLSD/Binary");
const std::string LLSD_XML_HEADER("LLSD/XML");
const std::string LLSD_NOTATION_HEADER("llsd/notation");
//used to deflate a gzipped asset (currently used for navmeshes)
#define windowBits 15
@@ -81,6 +82,11 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize
f = new LLSDXMLFormatter;
break;
case LLSD_NOTATION:
str << "<? " << LLSD_NOTATION_HEADER << " ?>\n";
f = new LLSDNotationFormatter;
break;
default:
LL_WARNS() << "serialize request for unknown ELLSD_Serialize" << LL_ENDL;
}
@@ -168,6 +174,10 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
{
p = new LLSDXMLParser;
}
else if (header == LLSD_NOTATION_HEADER)
{
p = new LLSDNotationParser;
}
else
{
LL_WARNS() << "deserialize request for unknown ELLSD_Serialize" << LL_ENDL;

View File

@@ -694,7 +694,7 @@ class LL_COMMON_API LLSDSerialize
public:
enum ELLSD_Serialize
{
LLSD_BINARY, LLSD_XML
LLSD_BINARY, LLSD_XML, LLSD_NOTATION
};
/**

View File

@@ -192,6 +192,14 @@ char* ll_pretty_print_sd(const LLSD& sd)
return buffer;
}
std::string ll_stream_notation_sd(const LLSD& sd)
{
std::ostringstream stream;
stream << LLSDOStreamer<LLSDNotationFormatter>(sd);
return stream.str();
}
//compares the structure of an LLSD to a template LLSD and stores the
//"valid" values in a 3rd LLSD. Default values pulled from the template
//if the tested LLSD does not contain the key/value pair.
@@ -313,6 +321,180 @@ BOOL compare_llsd_with_template(
return TRUE;
}
// filter_llsd_with_template() is a direct clone (copy-n-paste) of
// compare_llsd_with_template with the following differences:
// (1) bool vs BOOL return types
// (2) A map with the key value "*" is a special value and maps any key in the
// test llsd that doesn't have an explicitly matching key in the template.
// (3) The element of an array with exactly one element is taken as a template
// for *all* the elements of the test array. If the template array is of
// different size, compare_llsd_with_template() semantics apply.
bool filter_llsd_with_template(
const LLSD & llsd_to_test,
const LLSD & template_llsd,
LLSD & resultant_llsd)
{
if (llsd_to_test.isUndefined() && template_llsd.isDefined())
{
resultant_llsd = template_llsd;
return true;
}
else if (llsd_to_test.type() != template_llsd.type())
{
resultant_llsd = LLSD();
return false;
}
if (llsd_to_test.isArray())
{
//they are both arrays
//we loop over all the items in the template
//verifying that the to_test has a subset (in the same order)
//any shortcoming in the testing_llsd are just taken
//to be the rest of the template
LLSD data;
LLSD::array_const_iterator test_iter;
LLSD::array_const_iterator template_iter;
resultant_llsd = LLSD::emptyArray();
test_iter = llsd_to_test.beginArray();
if (1 == template_llsd.size())
{
// If the template has a single item, treat it as
// the template for *all* items in the test LLSD.
template_iter = template_llsd.beginArray();
for (; test_iter != llsd_to_test.endArray(); ++test_iter)
{
if (! filter_llsd_with_template(*test_iter, *template_iter, data))
{
resultant_llsd = LLSD();
return false;
}
else
{
resultant_llsd.append(data);
}
}
}
else
{
// Traditional compare_llsd_with_template matching
for (template_iter = template_llsd.beginArray();
template_iter != template_llsd.endArray() &&
test_iter != llsd_to_test.endArray();
++template_iter, ++test_iter)
{
if (! filter_llsd_with_template(*test_iter, *template_iter, data))
{
resultant_llsd = LLSD();
return false;
}
else
{
resultant_llsd.append(data);
}
}
//so either the test or the template ended
//we do another loop now to the end of the template
//grabbing the default values
for (;
template_iter != template_llsd.endArray();
++template_iter)
{
resultant_llsd.append(*template_iter);
}
}
}
else if (llsd_to_test.isMap())
{
resultant_llsd = LLSD::emptyMap();
//now we loop over the keys of the two maps
//any excess is taken from the template
//excess is ignored in the test
// Special tag for wildcarded LLSD map key templates
const LLSD::String wildcard_tag("*");
const bool template_has_wildcard = template_llsd.has(wildcard_tag);
LLSD wildcard_value;
LLSD value;
const LLSD::map_const_iterator template_iter_end(template_llsd.endMap());
for (LLSD::map_const_iterator template_iter(template_llsd.beginMap());
template_iter_end != template_iter;
++template_iter)
{
if (wildcard_tag == template_iter->first)
{
wildcard_value = template_iter->second;
}
else if (llsd_to_test.has(template_iter->first))
{
//the test LLSD has the same key
if (! filter_llsd_with_template(llsd_to_test[template_iter->first],
template_iter->second,
value))
{
resultant_llsd = LLSD();
return false;
}
else
{
resultant_llsd[template_iter->first] = value;
}
}
else if (! template_has_wildcard)
{
// test llsd doesn't have it...take the
// template as default value
resultant_llsd[template_iter->first] = template_iter->second;
}
}
if (template_has_wildcard)
{
LLSD sub_value;
LLSD::map_const_iterator test_iter;
for (test_iter = llsd_to_test.beginMap();
test_iter != llsd_to_test.endMap();
++test_iter)
{
if (resultant_llsd.has(test_iter->first))
{
// Final value has test key, assume more specific
// template matched and we shouldn't modify it again.
continue;
}
else if (! filter_llsd_with_template(test_iter->second,
wildcard_value,
sub_value))
{
// Test value doesn't match wildcarded template
resultant_llsd = LLSD();
return false;
}
else
{
// Test value matches template, add the actuals.
resultant_llsd[test_iter->first] = sub_value;
}
}
}
}
else
{
//of same type...take the test llsd's value
resultant_llsd = llsd_to_test;
}
return true;
}
/*****************************************************************************
* Helpers for llsd_matches()
*****************************************************************************/
@@ -672,3 +854,104 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits)
return false; // pacify the compiler
}
}
// Construct a deep partial clone of of an LLSD object. primitive types share
// references, however maps, arrays and binary objects are duplicated. An optional
// filter may be include to exclude/include keys in a map.
LLSD llsd_clone(LLSD value, LLSD filter)
{
LLSD clone;
bool has_filter(filter.isMap());
switch (value.type())
{
case LLSD::TypeMap:
clone = LLSD::emptyMap();
for (LLSD::map_const_iterator itm = value.beginMap(); itm != value.endMap(); ++itm)
{
if (has_filter)
{
if (filter.has((*itm).first))
{
if (!filter[(*itm).first].asBoolean())
continue;
}
else if (filter.has("*"))
{
if (!filter["*"].asBoolean())
continue;
}
else
{
continue;
}
}
clone[(*itm).first] = llsd_clone((*itm).second, filter);
}
break;
case LLSD::TypeArray:
clone = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
clone.append(llsd_clone(*ita, filter));
}
break;
case LLSD::TypeBinary:
{
LLSD::Binary bin(value.asBinary().begin(), value.asBinary().end());
clone = LLSD::Binary(bin);
break;
}
default:
clone = value;
}
return clone;
}
LLSD llsd_shallow(LLSD value, LLSD filter)
{
LLSD shallow;
bool has_filter(filter.isMap());
if (value.isMap())
{
shallow = LLSD::emptyMap();
for (LLSD::map_const_iterator itm = value.beginMap(); itm != value.endMap(); ++itm)
{
if (has_filter)
{
if (filter.has((*itm).first))
{
if (!filter[(*itm).first].asBoolean())
continue;
}
else if (filter.has("*"))
{
if (!filter["*"].asBoolean())
continue;
}
else
{
continue;
}
}
shallow[(*itm).first] = (*itm).second;
}
}
else if (value.isArray())
{
shallow = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
shallow.append(*ita);
}
}
else
{
return value;
}
return shallow;
}

View File

@@ -30,6 +30,7 @@
#define LL_LLSDUTIL_H
#include "llsd.h"
#include <boost/functional/hash.hpp>
// U32
LL_COMMON_API LLSD ll_sd_from_U32(const U32);
@@ -56,6 +57,8 @@ LL_COMMON_API char* ll_print_sd(const LLSD& sd);
LL_COMMON_API char* ll_pretty_print_sd_ptr(const LLSD* sd);
LL_COMMON_API char* ll_pretty_print_sd(const LLSD& sd);
LL_COMMON_API std::string ll_stream_notation_sd(const LLSD& sd);
//compares the structure of an LLSD to a template LLSD and stores the
//"valid" values in a 3rd LLSD. Default values
//are pulled from the template. Extra keys/values in the test
@@ -68,6 +71,19 @@ LL_COMMON_API BOOL compare_llsd_with_template(
const LLSD& template_llsd,
LLSD& resultant_llsd);
// filter_llsd_with_template() is a direct clone (copy-n-paste) of
// compare_llsd_with_template with the following differences:
// (1) bool vs BOOL return types
// (2) A map with the key value "*" is a special value and maps any key in the
// test llsd that doesn't have an explicitly matching key in the template.
// (3) The element of an array with exactly one element is taken as a template
// for *all* the elements of the test array. If the template array is of
// different size, compare_llsd_with_template() semantics apply.
bool filter_llsd_with_template(
const LLSD & llsd_to_test,
const LLSD & template_llsd,
LLSD & resultant_llsd);
/**
* Recursively determine whether a given LLSD data block "matches" another
* LLSD prototype. The returned string is empty() on success, non-empty() on
@@ -419,4 +435,87 @@ private:
} // namespace llsd
// Creates a deep clone of an LLSD object. Maps, Arrays and binary objects
// are duplicated, atomic primitives (Boolean, Integer, Real, etc) simply
// use a shared reference.
// Optionally a filter may be specified to control what is duplicated. The
// map takes the form "keyname/boolean".
// If the value is true the value will be duplicated otherwise it will be skipped
// when encountered in a map. A key name of "*" can be specified as a wild card
// and will specify the default behavior. If no wild card is given and the clone
// encounters a name not in the filter, that value will be skipped.
LLSD llsd_clone(LLSD value, LLSD filter = LLSD());
// Creates a shallow copy of a map or array. If passed any other type of LLSD
// object it simply returns that value. See llsd_clone for a description of
// the filter parameter.
LLSD llsd_shallow(LLSD value, LLSD filter = LLSD());
// Specialization for generating a hash value from an LLSD block.
namespace boost {
template<> struct hash<LLSD>
{
typedef LLSD argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const& s) const
{
result_type seed(0);
LLSD::Type stype = s.type();
boost::hash_combine(seed, (S32)stype);
switch (stype)
{
case LLSD::TypeBoolean:
boost::hash_combine(seed, s.asBoolean());
break;
case LLSD::TypeInteger:
boost::hash_combine(seed, s.asInteger());
break;
case LLSD::TypeReal:
boost::hash_combine(seed, s.asReal());
break;
case LLSD::TypeURI:
case LLSD::TypeString:
boost::hash_combine(seed, s.asString());
break;
case LLSD::TypeUUID:
boost::hash_combine(seed, s.asUUID());
break;
case LLSD::TypeDate:
boost::hash_combine(seed, s.asDate().secondsSinceEpoch());
break;
case LLSD::TypeBinary:
{
const LLSD::Binary &b(s.asBinary());
boost::hash_range(seed, b.begin(), b.end());
break;
}
case LLSD::TypeMap:
{
for (LLSD::map_const_iterator itm = s.beginMap(); itm != s.endMap(); ++itm)
{
boost::hash_combine(seed, (*itm).first);
boost::hash_combine(seed, (*itm).second);
}
break;
}
case LLSD::TypeArray:
for (LLSD::array_const_iterator ita = s.beginArray(); ita != s.endArray(); ++ita)
{
boost::hash_combine(seed, (*ita));
}
break;
case LLSD::TypeUndefined:
default:
break;
}
return seed;
}
};
}
#endif // LL_LLSDUTIL_H

View File

@@ -233,7 +233,7 @@ llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len)
{
out += cur_char;
}
i++;
++i;
}
return out;
}
@@ -493,7 +493,7 @@ std::string wstring_to_utf8str(const LLWString& utf32str, S32 len)
std::string out;
out.reserve(len);
for (S32 i = 0; i < len; i++)
for (S32 i = 0; i < len; ++i)
{
S32 n = wchar_to_utf8chars(utf32str[i], tchars);
tchars[n] = 0;
@@ -576,6 +576,78 @@ std::string utf8str_truncate(const std::string& utf8str, const S32 max_len)
}
}
// [RLVa:KB] - Checked: RLVa-2.1.0
std::string utf8str_substr(const std::string& utf8str, const S32 index, const S32 max_len)
{
if (0 == max_len)
{
return std::string();
}
if (utf8str.length() - index <= max_len)
{
return utf8str.substr(index, max_len);
}
else
{
S32 cur_char = max_len;
// If we're ASCII, we don't need to do anything
if ((U8)utf8str[index + cur_char] > 0x7f)
{
// If first two bits are (10), it's the tail end of a multibyte char. We need to shift back
// to the first character
while (0x80 == (0xc0 & utf8str[index + cur_char]))
{
cur_char--;
// Keep moving forward until we hit the first char;
if (cur_char == 0)
{
// Make sure we don't trash memory if we've got a bogus string.
break;
}
}
}
// The byte index we're on is one we want to get rid of, so we only want to copy up to (cur_char-1) chars
return utf8str.substr(index, cur_char);
}
}
void utf8str_split(std::list<std::string>& split_list, const std::string& utf8str, size_t maxlen, char split_token)
{
split_list.clear();
std::string::size_type lenMsg = utf8str.length(), lenIt = 0;
const char* pstrIt = utf8str.c_str(); std::string strTemp;
while (lenIt < lenMsg)
{
if (lenIt + maxlen < lenMsg)
{
// Find the last split character
const char* pstrTemp = pstrIt + maxlen;
while ( (pstrTemp > pstrIt) && (*pstrTemp != split_token) )
pstrTemp--;
if (pstrTemp > pstrIt)
strTemp = utf8str.substr(lenIt, pstrTemp - pstrIt);
else
strTemp = utf8str_substr(utf8str, lenIt, maxlen);
}
else
{
strTemp = utf8str.substr(lenIt, std::string::npos);
}
split_list.push_back(strTemp);
lenIt += strTemp.length();
pstrIt = utf8str.c_str() + lenIt;
if (*pstrIt == split_token)
lenIt++;
}
}
// [/RLVa:KB]
std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len)
{
if (0 == symbol_len)
@@ -668,6 +740,12 @@ bool LLStringOps::isHexString(const std::string& str)
}
#if LL_WINDOWS
std::string ll_convert_wide_to_string(const wchar_t* in)
{
return ll_convert_wide_to_string(in, CP_UTF8);
}
std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
{
std::string out;
@@ -705,6 +783,11 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
return out;
}
wchar_t* ll_convert_string_to_wide(const std::string& in)
{
return ll_convert_string_to_wide(in, CP_UTF8);
}
wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
{
// From review:
@@ -726,6 +809,67 @@ wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page
w_out[real_output_str_len] = 0;
return w_out;
return {&w_out[0]};
}
S32 wchartchars_to_llwchar(const std::wstring::value_type* inchars, llwchar* outchar)
{
const std::wstring::value_type* base = inchars;
std::wstring::value_type cur_char = *inchars++;
llwchar char32 = cur_char;
if ((cur_char >= 0xD800) && (cur_char <= 0xDFFF))
{
// Surrogates
char32 = ((llwchar)(cur_char - 0xD800)) << 10;
cur_char = *inchars++;
char32 += (llwchar)(cur_char - 0xDC00) + 0x0010000UL;
}
else
{
char32 = (llwchar)cur_char;
}
*outchar = char32;
return inchars - base;
}
LLWString ll_convert_wide_to_wstring(const std::wstring& in)
{
LLWString wout;
auto len = in.size();
if ((len <= 0) || in.empty()) return wout;
size_t i = 0;
// craziness to make gcc happy (llutf16string.c_str() is tweaked on linux):
const std::wstring::value_type* chars16 = &(*(in.begin()));
while (i < len)
{
llwchar cur_char;
i += wchartchars_to_llwchar(chars16 + i, &cur_char);
wout += cur_char;
}
return wout;
}
std::wstring ll_convert_wstring_to_wide(const LLWString& in)
{
std::wstring out;
size_t i = 0;
while (i < in.size())
{
U32 cur_char = in[i];
if (cur_char > 0xFFFF)
{
out += (0xD7C0 + (cur_char >> 10));
out += (0xDC00 | (cur_char & 0x3FF));
}
else
{
out += cur_char;
}
i++;
}
return out;
}
std::string ll_convert_string_to_utf8_string(const std::string& in)
@@ -736,7 +880,108 @@ std::string ll_convert_string_to_utf8_string(const std::string& in)
return out_utf8;
}
#endif // LL_WINDOWS
namespace
{
void HeapFree_deleter(void* ptr)
{
// instead of LocalFree(), per https://stackoverflow.com/a/31541205
HeapFree(GetProcessHeap(), NULL, ptr);
}
} // anonymous namespace
template<>
std::wstring windows_message<std::wstring>(DWORD error)
{
// derived from https://stackoverflow.com/a/455533
wchar_t* rawptr = nullptr;
auto okay = FormatMessageW(
// use system message tables for GetLastError() codes
FORMAT_MESSAGE_FROM_SYSTEM |
// internally allocate buffer and return its pointer
FORMAT_MESSAGE_ALLOCATE_BUFFER |
// you cannot pass insertion parameters (thanks Gandalf)
FORMAT_MESSAGE_IGNORE_INSERTS |
// ignore line breaks in message definition text
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL, // lpSource, unused with FORMAT_MESSAGE_FROM_SYSTEM
error, // dwMessageId
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageId
(LPWSTR)&rawptr, // lpBuffer: force-cast wchar_t** to wchar_t*
0, // nSize, unused with FORMAT_MESSAGE_ALLOCATE_BUFFER
NULL); // Arguments, unused
// make a unique_ptr from rawptr so it gets cleaned up properly
std::unique_ptr<wchar_t, void(*)(void*)> bufferptr(rawptr, HeapFree_deleter);
if (okay && bufferptr)
{
// got the message, return it ('okay' is length in characters)
return { bufferptr.get(), okay };
}
// did not get the message, synthesize one
auto format_message_error = GetLastError();
std::wostringstream out;
out << L"GetLastError() " << error << L" (FormatMessageW() failed with "
<< format_message_error << L")";
return out.str();
}
boost::optional<std::wstring> llstring_getoptenv(const std::string& key)
{
auto wkey = ll_convert_string_to_wide(key);
// Take a wild guess as to how big the buffer should be.
std::vector<wchar_t> buffer(1024);
auto n = GetEnvironmentVariableW(wkey, &buffer[0], buffer.size());
// If our initial guess was too short, n will indicate the size (in
// wchar_t's) that buffer should have been, including the terminating nul.
if (n > (buffer.size() - 1))
{
// make it big enough
buffer.resize(n);
// and try again
n = GetEnvironmentVariableW(wkey, &buffer[0], buffer.size());
}
// did that (ultimately) succeed?
if (n)
{
// great, return populated boost::optional
return boost::optional<std::wstring>(&buffer[0]);
}
// not successful
auto last_error = GetLastError();
// Don't bother warning for NOT_FOUND; that's an expected case
if (last_error != ERROR_ENVVAR_NOT_FOUND)
{
LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: "
<< windows_message<std::string>(last_error) << LL_ENDL;
}
// return empty boost::optional
return {};
}
#else // ! LL_WINDOWS
boost::optional<std::string> llstring_getoptenv(const std::string& key)
{
auto found = getenv(key.c_str());
if (found)
{
// return populated boost::optional
return boost::optional<std::string>(found);
}
else
{
// return empty boost::optional
return {};
}
}
#endif // ! LL_WINDOWS
long LLStringOps::sPacificTimeOffset = 0;
long LLStringOps::sLocalTimeOffset = 0;

View File

@@ -27,6 +27,9 @@
#ifndef LL_LLSTRING_H
#define LL_LLSTRING_H
#include "llwin32headerslean.h"
#include <boost/optional/optional.hpp>
#include <string>
#include <cstdio>
//#include <locale>
@@ -34,8 +37,12 @@
#include <algorithm>
#include <vector>
#include <map>
#include "llsd.h"
#include "llfasttimer.h"
#include "llformat.h"
#include "llsd.h"
// [RLVa:KB] - Checked: RLVa-2.1.0
#include <list>
// [/RLVa:KB]
#if LL_LINUX || LL_SOLARIS
#include <wctype.h>
@@ -305,7 +312,7 @@ public:
static bool isValidIndex(const string_type& string, size_type i)
{
return !string.empty() && (i <= string.size());
return !string.empty() && (0 <= i) && (i <= string.size());
}
static bool contains(const string_type& string, T c, size_type i=0)
@@ -343,6 +350,19 @@ public:
const string_type& string,
const string_type& substr);
/**
* get environment string value with proper Unicode handling
* (key is always UTF-8)
* detect absence by return value == dflt
*/
static string_type getenv(const std::string& key, const string_type& dflt="");
/**
* get optional environment string value with proper Unicode handling
* (key is always UTF-8)
* detect absence by (! return value)
*/
static boost::optional<string_type> getoptenv(const std::string& key);
static void addCRLF(string_type& string);
static void removeCRLF(string_type& string);
static void removeWindowsCR(string_type& string);
@@ -503,6 +523,37 @@ LL_COMMON_API bool iswindividual(llwchar elem);
* Unicode support
*/
/// generic conversion aliases
template<typename TO, typename FROM, typename Enable=void>
struct ll_convert_impl
{
// Don't even provide a generic implementation. We specialize for every
// combination we do support.
TO operator()(const FROM& in) const;
};
// Use a function template to get the nice ll_convert<TO>(from_value) API.
template<typename TO, typename FROM>
TO ll_convert(const FROM& in)
{
return ll_convert_impl<TO, FROM>()(in);
}
// degenerate case
template<typename T>
struct ll_convert_impl<T, T>
{
T operator()(const T& in) const { return in; }
};
// specialize ll_convert_impl<TO, FROM> to return EXPR
#define ll_convert_alias(TO, FROM, EXPR) \
template<> \
struct ll_convert_impl<TO, FROM> \
{ \
TO operator()(const FROM& in) const { return EXPR; } \
}
// Make the incoming string a utf8 string. Replaces any unknown glyph
// with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest
// of the data may not be recovered.
@@ -510,37 +561,91 @@ LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw);
//
// We should never use UTF16 except when communicating with Win32!
//
// https://docs.microsoft.com/en-us/cpp/cpp/char-wchar-t-char16-t-char32-t
// nat 2018-12-14: I consider the whole llutf16string thing a mistake, because
// the Windows APIs we want to call are all defined in terms of wchar_t*
// (or worse, LPCTSTR).
// https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types
// While there is no point coding for an ASCII-only world (! defined(UNICODE)),
// use of U16 and llutf16string for Windows APIs locks in /Zc:wchar_t-. Going
// forward, we should code in terms of wchar_t and std::wstring so as to
// support either setting of /Zc:wchar_t.
// The first link above states that char can be used to hold ASCII or any
// multi-byte character set, and distinguishes wchar_t (UTF-16LE), char16_t
// (UTF-16) and char32_t (UTF-32). Nonetheless, within this code base:
// * char and std::string always hold UTF-8 (of which ASCII is a subset). It
// is a BUG if they are used to pass strings in any other multi-byte
// encoding.
// * wchar_t and std::wstring should be our interface to Windows wide-string
// APIs, and therefore hold UTF-16LE.
// * U16 and llutf16string are the previous but DEPRECATED UTF-16LE type. Do
// not introduce new uses of U16 or llutf16string for string data.
// * llwchar and LLWString hold UTF-32 strings.
// * Do not introduce char16_t or std::u16string.
// * Do not introduce char32_t or std::u32string.
//
#if _WIN32 && _NATIVE_WCHAR_T_DEFINED
typedef wchar_t utf16strtype;
#else
typedef U16 utf16strtype;
#endif
typedef std::basic_string<utf16strtype> llutf16string;
#if ! defined(LL_WCHAR_T_NATIVE)
// wchar_t is identical to U16, and std::wstring is identical to llutf16string.
// Defining an ll_convert alias involving llutf16string would collide with the
// comparable preferred alias involving std::wstring. (In this scenario, if
// you pass llutf16string, it will engage the std::wstring specialization.)
#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing
#else // defined(LL_WCHAR_T_NATIVE)
// wchar_t is a distinct native type, so llutf16string is also a distinct
// type, and there IS a point to converting separately to/from llutf16string.
// (But why? Windows APIs are still defined in terms of wchar_t, and
// in this scenario llutf16string won't work for them!)
#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
#if LL_WINDOWS
// LL_WCHAR_T_NATIVE is defined on non-Windows systems because, in fact,
// wchar_t is native. Everywhere but Windows, we use it for llwchar (see
// stdtypes.h). That makes LLWString identical to std::wstring, so these
// aliases for std::wstring would collide with those for LLWString. Only
// define on Windows, where converting between std::wstring and llutf16string
// means copying chars.
ll_convert_alias(llutf16string, std::wstring, llutf16string(in.begin(), in.end()));
ll_convert_alias(std::wstring, llutf16string, std::wstring(in.begin(), in.end()));
#endif // LL_WINDOWS
#endif // defined(LL_WCHAR_T_NATIVE)
LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len);
LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str);
ll_convert_u16_alias(LLWString, llutf16string, utf16str_to_wstring(in));
LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len);
LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str);
ll_convert_u16_alias(llutf16string, LLWString, wstring_to_utf16str(in));
LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len);
LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str );
ll_convert_u16_alias(llutf16string, std::string, utf8str_to_utf16str(in));
LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len);
LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str);
// Same function, better name. JC
inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); }
// best name of all
ll_convert_alias(LLWString, std::string, utf8string_to_wstring(in));
//
LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str);
ll_convert_alias(std::string, LLWString, wstring_to_utf8str(in));
LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len);
LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str);
ll_convert_u16_alias(std::string, llutf16string, utf16str_to_utf8str(in));
#if LL_WINDOWS
inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);}
@@ -575,6 +680,11 @@ LL_COMMON_API S32 wstring_wstring_length_from_utf16_length(const LLWString & wst
*/
LL_COMMON_API std::string utf8str_truncate(const std::string& utf8str, const S32 max_len);
// [RLVa:KB] - Checked: RLVa-2.1.0
LL_COMMON_API std::string utf8str_substr(const std::string& utf8str, const S32 index, const S32 max_len);
LL_COMMON_API void utf8str_split(std::list<std::string>& split_list, const std::string& utf8str, size_t maxlen, char split_token);
// [/RLVa:KB]
LL_COMMON_API std::string utf8str_trim(const std::string& utf8str);
LL_COMMON_API S32 utf8str_compare_insensitive(
@@ -623,22 +733,77 @@ LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
* This replaces the unsafe W2A macro from ATL.
*/
LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page);
LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); // default CP_UTF8
inline std::string ll_convert_wide_to_string(const std::wstring& in, unsigned int code_page)
{
return ll_convert_wide_to_string(in.c_str(), code_page);
}
inline std::string ll_convert_wide_to_string(const std::wstring& in)
{
return ll_convert_wide_to_string(in.c_str());
}
ll_convert_alias(std::string, std::wstring, ll_convert_wide_to_string(in));
/**
* Converts a string to wide string.
*
* It will allocate memory for result string with "new []". Don't forget to release it with "delete []".
*/
LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page);
LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in,
unsigned int code_page);
LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in);
// default CP_UTF8
ll_convert_alias(wchar_t*, std::string, ll_convert_string_to_wide(in));
/**
* Converts incoming string into urf8 string
* Convert a Windows wide string to our LLWString
*/
LL_COMMON_API LLWString ll_convert_wide_to_wstring(const std::wstring& in);
ll_convert_alias(LLWString, std::wstring, ll_convert_wide_to_wstring(in));
/**
* Convert LLWString to Windows wide string
*/
LL_COMMON_API std::wstring ll_convert_wstring_to_wide(const LLWString& in);
ll_convert_alias(std::wstring, LLWString, ll_convert_wstring_to_wide(in));
/**
* Converts incoming string into utf8 string
*
*/
LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in);
/// Get Windows message string for passed GetLastError() code
// VS 2013 doesn't let us forward-declare this template, which is what we
// started with, so the implementation could reference the specialization we
// haven't yet declared. Somewhat weirdly, just stating the generic
// implementation in terms of the specialization works, even in this order...
// the general case is just a conversion from the sole implementation
// Microsoft says DWORD is a typedef for unsigned long
// https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types
// so rather than drag windows.h into everybody's include space...
template<typename STRING>
STRING windows_message(unsigned long error)
{
return ll_convert<STRING>(windows_message<std::wstring>(error));
}
/// There's only one real implementation
template<>
LL_COMMON_API std::wstring windows_message<std::wstring>(unsigned long error);
/// Get Windows message string, implicitly calling GetLastError()
template<typename STRING>
STRING windows_message() { return windows_message<STRING>(GetLastError()); }
//@}
#endif // LL_WINDOWS
LL_COMMON_API boost::optional<std::wstring> llstring_getoptenv(const std::string& key);
#else // ! LL_WINDOWS
LL_COMMON_API boost::optional<std::string> llstring_getoptenv(const std::string& key);
#endif // ! LL_WINDOWS
/**
* Many of the 'strip' and 'replace' methods of LLStringUtilBase need
@@ -1612,6 +1777,37 @@ bool LLStringUtilBase<T>::endsWith(
return (idx == (string.size() - substr.size()));
}
// static
template<class T>
auto LLStringUtilBase<T>::getoptenv(const std::string& key) -> boost::optional<string_type>
{
auto found(llstring_getoptenv(key));
if (found)
{
// return populated boost::optional
return { ll_convert<string_type>(*found) };
}
else
{
// empty boost::optional
return {};
}
}
// static
template<class T>
auto LLStringUtilBase<T>::getenv(const std::string& key, const string_type& dflt) -> string_type
{
auto found(getoptenv(key));
if (found)
{
return *found;
}
else
{
return dflt;
}
}
template<class T>
BOOL LLStringUtilBase<T>::convertToBOOL(const string_type& string, BOOL& value)

View File

@@ -132,23 +132,34 @@ struct LLUnit
return mValue;
}
LL_FORCE_INLINE void value(storage_t value)
LL_FORCE_INLINE void value(const storage_t& value)
{
mValue = value;
}
template<typename NEW_UNITS>
storage_t valueInUnits()
storage_t valueInUnits() const
{
return LLUnit<storage_t, NEW_UNITS>(*this).value();
}
template<typename NEW_UNITS>
void valueInUnits(storage_t value)
void valueInUnits(const storage_t& value) const
{
*this = LLUnit<storage_t, NEW_UNITS>(value);
}
LL_FORCE_INLINE operator storage_t() const
{
return value();
}
/*LL_FORCE_INLINE self_t& operator= (storage_t v)
{
value(v);
return *this;
}*/
LL_FORCE_INLINE void operator += (self_t other)
{
mValue += convert(other).mValue;
@@ -159,60 +170,60 @@ struct LLUnit
mValue -= convert(other).mValue;
}
LL_FORCE_INLINE void operator *= (storage_t multiplicand)
LL_FORCE_INLINE void operator *= (const storage_t& multiplicand)
{
mValue *= multiplicand;
}
LL_FORCE_INLINE void operator *= (self_t multiplicand)
LL_FORCE_INLINE void operator *= (const self_t& multiplicand)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "Multiplication of unit types not supported.");
}
LL_FORCE_INLINE void operator /= (storage_t divisor)
LL_FORCE_INLINE void operator /= (const storage_t& divisor)
{
mValue /= divisor;
}
void operator /= (self_t divisor)
void operator /= (const self_t& divisor)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "Illegal in-place division of unit types.");
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator == (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator == (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue == convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator != (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator != (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue != convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator < (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator < (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue < convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator <= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator <= (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue <= convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator > (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator > (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue > convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator >= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator >= (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue >= convert(other).value();
}

View File

@@ -32,7 +32,6 @@
#include <string>
class LLSD;
class LLUUID;
class LLApp;
/**

View File

@@ -31,6 +31,7 @@
#include <vector>
#include <functional>
#include <boost/functional/hash.hpp>
#include <boost/unordered_set.hpp>
#include "stdtypes.h"
#include "llpreprocessor.h"
@@ -289,7 +290,7 @@ inline U32 LLUUID::getCRC32() const
}
typedef std::vector<LLUUID> uuid_vec_t;
typedef std::set<LLUUID> uuid_set_t;
typedef boost::unordered_set<LLUUID> uuid_set_t;
// Helper structure for ordering lluuids in stl containers. eg:
// std::map<LLUUID, LLWidget*, lluuid_less> widget_map;

View File

@@ -21,12 +21,17 @@ set(llinventory_SOURCE_FILES
llfoldertype.cpp
llinventory.cpp
llinventorydefines.cpp
llinventorysettings.cpp
llinventorytype.cpp
lllandmark.cpp
llnotecard.cpp
llparcel.cpp
llpermissions.cpp
llsaleinfo.cpp
llsettingsbase.cpp
llsettingsdaycycle.cpp
llsettingssky.cpp
llsettingswater.cpp
lltransactionflags.cpp
lluserrelations.cpp
)
@@ -39,7 +44,9 @@ set(llinventory_HEADER_FILES
llfoldertype.h
llinventory.h
llinventorydefines.h
llinventorysettings.h
llinventorytype.h
llinvtranslationbrdg.h
lllandmark.h
llnotecard.h
llparcel.h
@@ -47,6 +54,10 @@ set(llinventory_HEADER_FILES
llpermissions.h
llpermissionsflags.h
llsaleinfo.h
llsettingsbase.h
llsettingsdaycycle.h
llsettingssky.h
llsettingswater.h
lltransactionflags.h
lltransactiontypes.h
lluserrelations.h

View File

@@ -101,11 +101,15 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", TRUE));
addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", TRUE));
addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", TRUE));
addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", TRUE));
addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE));
addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", TRUE));
addEntry(LLFolderType::FT_SUITCASE, new FolderEntry("suitcase", TRUE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));

View File

@@ -97,6 +97,9 @@ public:
FT_MARKETPLACE_LISTINGS = 53,
FT_MARKETPLACE_STOCK = 54,
FT_MARKETPLACE_VERSION = 55, // Note: We actually *never* create folders with that type. This is used for icon override only.
FT_SETTINGS = 56,
FT_SUITCASE = 100,
FT_COUNT,

View File

@@ -1168,10 +1168,10 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
static U32 WT_UNKNOWN = 16; // LLWearableType::WT_UNKNOWN
static U32 WT_COUNT = 17; // LLWearableType::WT_COUNT
// The last 8 bits of mFlags contain the wearable type.
static U32 II_FLAGS_WEARABLES_MASK = 0xff; // LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK
static U32 II_FLAGS_SUBTYPE_MASK = 0xff; // LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK
// The wearable type is stored in the lower 8 bits of mFlags.
U32 wt = mFlags & II_FLAGS_WEARABLES_MASK;
U32 wt = mFlags & II_FLAGS_SUBTYPE_MASK;
// Because WT_UNKNOWN now has locally a special meaning, make sure we don't receive it from the server.
if (wt == WT_UNKNOWN)

View File

@@ -2,33 +2,26 @@
* @file llinventorydefines.cpp
* @brief Implementation of the inventory defines.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2010, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlife.com/developers/opensource/flossexception
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
*/
#include "linden_common.h"

View File

@@ -2,33 +2,26 @@
* @file llinventorydefines.h
* @brief LLInventoryDefines
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2010, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlife.com/developers/opensource/flossexception
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
*/
#ifndef LL_LLINVENTORYDEFINES_H
@@ -88,9 +81,10 @@ public:
II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS = 0x200000,
// Whether a returned object is composed of multiple items.
II_FLAGS_WEARABLES_MASK = 0xff,
// Wearables use the low order byte of flags to store the
// LLWearableType::EType enumeration found in newview/llwearable.h
II_FLAGS_SUBTYPE_MASK = 0x0000ff,
// Some items like Wearables and settings use the low order byte
// of flags to store the sub type of the inventory item.
// see LLWearableType::EType enumeration found in newview/llwearable.h
II_FLAGS_PERM_OVERWRITE_MASK = (II_FLAGS_OBJECT_SLAM_PERM |
II_FLAGS_OBJECT_SLAM_SALE |

View File

@@ -0,0 +1,117 @@
/**
* @file llinventorysettings.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llinventorysettings.h"
#include "llinventorytype.h"
#include "llinventorydefines.h"
#include "lldictionary.h"
#include "llsingleton.h"
#include "llinvtranslationbrdg.h"
//=========================================================================
namespace {
LLTranslationBridge::ptr_t sTranslator;
}
//=========================================================================
struct SettingsEntry : public LLDictionaryEntry
{
SettingsEntry(const std::string &name,
const std::string& default_new_name,
LLInventoryType::EIconName iconName) :
LLDictionaryEntry(name),
mDefaultNewName(default_new_name),
mLabel(name),
mIconName(iconName)
{
std::string transdname = sTranslator->getString(mLabel);
if (!transdname.empty())
{
mLabel = transdname;
}
}
std::string mLabel;
std::string mDefaultNewName; //keep mLabel for backward compatibility
LLInventoryType::EIconName mIconName;
};
class LLSettingsDictionary : public LLSingleton<LLSettingsDictionary>,
public LLDictionary<LLSettingsType::type_e, SettingsEntry>
{
friend class LLSingleton<LLSettingsDictionary>; \
LLSettingsDictionary();
void initSingleton();
};
LLSettingsDictionary::LLSettingsDictionary()
{
}
void LLSettingsDictionary::initSingleton()
{
addEntry(LLSettingsType::ST_SKY, new SettingsEntry("sky", "New Sky", LLInventoryType::ICONNAME_SETTINGS_SKY));
addEntry(LLSettingsType::ST_WATER, new SettingsEntry("water", "New Water", LLInventoryType::ICONNAME_SETTINGS_WATER));
addEntry(LLSettingsType::ST_DAYCYCLE, new SettingsEntry("day", "New Day", LLInventoryType::ICONNAME_SETTINGS_DAY));
addEntry(LLSettingsType::ST_NONE, new SettingsEntry("none", "New Settings", LLInventoryType::ICONNAME_SETTINGS));
addEntry(LLSettingsType::ST_INVALID, new SettingsEntry("invalid", "New Settings", LLInventoryType::ICONNAME_SETTINGS));
}
//=========================================================================
LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags)
{
return (LLSettingsType::type_e)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
}
LLInventoryType::EIconName LLSettingsType::getIconName(LLSettingsType::type_e type)
{
const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type);
if (!entry)
return getIconName(ST_INVALID);
return entry->mIconName;
}
std::string LLSettingsType::getDefaultName(LLSettingsType::type_e type)
{
const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type);
if (!entry)
return getDefaultName(ST_INVALID);
return entry->mDefaultNewName;
}
void LLSettingsType::initClass(LLTranslationBridge::ptr_t &trans)
{
sTranslator = trans;
}
void LLSettingsType::cleanupClass()
{
sTranslator.reset();
}

View File

@@ -0,0 +1,56 @@
/**
* @file llinventorysettings.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_INVENTORY_SETTINGS_H
#define LL_INVENTORY_SETTINGS_H
#include "llinventorytype.h"
#include "llinvtranslationbrdg.h"
class LLSettingsType
{
public:
enum type_e
{
ST_SKY = 0,
ST_WATER = 1,
ST_DAYCYCLE = 2,
ST_INVALID = 255,
ST_NONE = -1
};
static type_e fromInventoryFlags(U32 flags);
static LLInventoryType::EIconName getIconName(type_e type);
static std::string getDefaultName(type_e type);
static void initClass(LLTranslationBridge::ptr_t &trans);
static void cleanupClass();
};
#endif

View File

@@ -191,7 +191,7 @@ LLInventoryType::EType LLInventoryType::defaultForAssetType(LLAssetType::EType a
}
else
{
return IT_NONE;
return IT_UNKNOWN;
}
}
@@ -210,6 +210,12 @@ bool LLInventoryType::cannotRestrictPermissions(LLInventoryType::EType type)
}
}
// Should show permissions that apply only to objects rezed in world.
bool LLInventoryType::showInWorldPermissions(LLInventoryType::EType type)
{
return (type != IT_SETTINGS);
}
bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type,
LLAssetType::EType asset_type)
{

View File

@@ -135,6 +135,8 @@ public:
// true if this type cannot have restricted permissions.
static bool cannotRestrictPermissions(EType type);
static bool showInWorldPermissions(EType type);
private:
// don't instantiate or derive one of these objects
LLInventoryType( void );

View File

@@ -0,0 +1,43 @@
/**
* @file llinvtranslationbrdg.h
* @brief Translation adapter for inventory.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_TRANSLATIONBRDG_H
#define LL_TRANSLATIONBRDG_H
#include <memory>
class LLTranslationBridge
{
public:
typedef std::shared_ptr<LLTranslationBridge> ptr_t;
// clang needs this to be happy
virtual ~LLTranslationBridge() {}
virtual std::string getString(const std::string &xml_desc) = 0;
};
#endif

View File

@@ -230,6 +230,9 @@ void LLParcel::init(const LLUUID &owner_id,
setAllowGroupAVSounds(TRUE);
setAllowAnyAVSounds(TRUE);
setHaveNewParcelLimitData(FALSE);
setRegionAllowEnvironmentOverride(FALSE);
setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION);
}
void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned)

View File

@@ -40,6 +40,7 @@
#include "llpermissions.h"
#include "lltimer.h"
#include "v3math.h"
#include "llsettingsdaycycle.h"
// Grid out of which parcels taken is stepped every 4 meters.
const F32 PARCEL_GRID_STEP_METERS = 4.f;
@@ -105,6 +106,10 @@ const U32 RT_SELL = 0x1 << 5;
const S32 INVALID_PARCEL_ID = -1;
const S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2;
// if Region settings are used, parcel env. version is -1
const S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1;
// Timeouts for parcels
// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000
const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000);
@@ -508,6 +513,13 @@ public:
{ return mRegionDenyAnonymousOverride; }
BOOL getRegionDenyAgeUnverifiedOverride() const
{ return mRegionDenyAgeUnverifiedOverride; }
BOOL getRegionAllowAccessOverride() const
{ return mRegionAllowAccessoverride; }
BOOL getRegionAllowEnvironmentOverride() const
{ return mRegionAllowEnvironmentOverride; }
S32 getParcelEnvironmentVersion() const
{ return mCurrentEnvironmentVersion; }
BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; }
BOOL getAllowAnyAVSounds() const { return mAllowAnyAVSounds; }
@@ -593,6 +605,10 @@ public:
void setRegionPushOverride(BOOL override) {mRegionPushOverride = override; }
void setRegionDenyAnonymousOverride(BOOL override) { mRegionDenyAnonymousOverride = override; }
void setRegionDenyAgeUnverifiedOverride(BOOL override) { mRegionDenyAgeUnverifiedOverride = override; }
void setRegionAllowAccessOverride(BOOL override) { mRegionAllowAccessoverride = override; }
void setRegionAllowEnvironmentOverride(BOOL override) { mRegionAllowEnvironmentOverride = override; }
void setParcelEnvironmentVersion(S32 version) { mCurrentEnvironmentVersion = version; }
// Accessors for parcel sellWithObjects
void setPreviousOwnerID(LLUUID prev_owner) { mPreviousOwnerID = prev_owner; }
@@ -603,7 +619,6 @@ public:
BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; }
BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; }
protected:
LLUUID mID;
LLUUID mOwnerID;
@@ -674,9 +689,13 @@ protected:
BOOL mRegionPushOverride;
BOOL mRegionDenyAnonymousOverride;
BOOL mRegionDenyAgeUnverifiedOverride;
BOOL mRegionAllowAccessoverride;
BOOL mRegionAllowEnvironmentOverride;
BOOL mAllowGroupAVSounds;
BOOL mAllowAnyAVSounds;
S32 mCurrentEnvironmentVersion;
bool mIsDefaultDayCycle;
public:
// HACK, make private

View File

@@ -0,0 +1,758 @@
/**
* @file llsettingsbase.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llsettingsbase.h"
#include "llmath.h"
#include <algorithm>
#include "llsdserialize.h"
//=========================================================================
namespace
{
const LLSettingsBase::TrackPosition BREAK_POINT = 0.5;
}
const LLSettingsBase::TrackPosition LLSettingsBase::INVALID_TRACKPOS(-1.0);
//=========================================================================
std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings)
{
LLSDSerialize::serialize(settings.getSettings(), os, LLSDSerialize::LLSD_NOTATION);
return os;
}
//=========================================================================
const std::string LLSettingsBase::SETTING_ID("id");
const std::string LLSettingsBase::SETTING_NAME("name");
const std::string LLSettingsBase::SETTING_HASH("hash");
const std::string LLSettingsBase::SETTING_TYPE("type");
const std::string LLSettingsBase::SETTING_ASSETID("asset_id");
const std::string LLSettingsBase::SETTING_FLAGS("flags");
const U32 LLSettingsBase::FLAG_NOCOPY(0x01 << 0);
const U32 LLSettingsBase::FLAG_NOMOD(0x01 << 1);
const U32 LLSettingsBase::FLAG_NOTRANS(0x01 << 2);
const U32 LLSettingsBase::Validator::VALIDATION_PARTIAL(0x01 << 0);
//=========================================================================
LLSettingsBase::LLSettingsBase():
mSettings(LLSD::emptyMap()),
mDirty(true),
mAssetID(),
mBlendedFactor(0.0)
{
}
LLSettingsBase::LLSettingsBase(const LLSD setting) :
mSettings(setting),
mDirty(true),
mAssetID(),
mBlendedFactor(0.0)
{
}
//=========================================================================
void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 mix)
{
mSettings = interpolateSDMap(mSettings, other.mSettings, other.getParameterMap(), mix);
setDirtyFlag(true);
}
LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) const
{
LLSD newSettings;
for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
LLSD::Type setting_type = value.type();
switch (setting_type)
{
case LLSD::TypeMap:
newSettings[key_name] = combineSDMaps(value, LLSD());
break;
case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
newSettings[key_name].append(*ita);
}
break;
//case LLSD::TypeInteger:
//case LLSD::TypeReal:
//case LLSD::TypeBoolean:
//case LLSD::TypeString:
//case LLSD::TypeUUID:
//case LLSD::TypeURI:
//case LLSD::TypeDate:
//case LLSD::TypeBinary:
default:
newSettings[key_name] = value;
break;
}
}
if (!other.isUndefined())
{
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
LLSD::Type setting_type = value.type();
switch (setting_type)
{
case LLSD::TypeMap:
newSettings[key_name] = combineSDMaps(value, LLSD());
break;
case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
newSettings[key_name].append(*ita);
}
break;
//case LLSD::TypeInteger:
//case LLSD::TypeReal:
//case LLSD::TypeBoolean:
//case LLSD::TypeString:
//case LLSD::TypeUUID:
//case LLSD::TypeURI:
//case LLSD::TypeDate:
//case LLSD::TypeBinary:
default:
newSettings[key_name] = value;
break;
}
}
}
return newSettings;
}
LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, F64 mix) const
{
LLSD newSettings;
stringset_t skip = getSkipInterpolateKeys();
stringset_t slerps = getSlerpKeys();
for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
if (skip.find(key_name) != skip.end())
continue;
LLSD other_value;
if (other.has(key_name))
{
other_value = other[key_name];
}
else
{
parammapping_t::const_iterator def_iter = defaults.find(key_name);
if (def_iter != defaults.end())
{
other_value = def_iter->second.getDefaultValue();
}
else if (value.type() == LLSD::TypeMap)
{
// interpolate in case there are defaults inside (part of legacy)
other_value = LLSDMap();
}
else
{
// The other or defaults does not contain this setting, keep the original value
// TODO: Should I blend this out instead?
newSettings[key_name] = value;
continue;
}
}
newSettings[key_name] = interpolateSDValue(key_name, value, other_value, defaults, mix, slerps);
}
// Special handling cases
// Flags
if (settings.has(SETTING_FLAGS))
{
U32 flags = (U32)settings[SETTING_FLAGS].asInteger();
if (other.has(SETTING_FLAGS))
flags |= (U32)other[SETTING_FLAGS].asInteger();
newSettings[SETTING_FLAGS] = LLSD::Integer(flags);
}
// Now add anything that is in other but not in the settings
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
std::string key_name = (*it).first;
if (skip.find(key_name) != skip.end())
continue;
if (settings.has(key_name))
continue;
parammapping_t::const_iterator def_iter = defaults.find(key_name);
if (def_iter != defaults.end())
{
// Blend against default value
newSettings[key_name] = interpolateSDValue(key_name, def_iter->second.getDefaultValue(), (*it).second, defaults, mix, slerps);
}
else if ((*it).second.type() == LLSD::TypeMap)
{
// interpolate in case there are defaults inside (part of legacy)
newSettings[key_name] = interpolateSDValue(key_name, LLSDMap(), (*it).second, defaults, mix, slerps);
}
// else do nothing when no known defaults
// TODO: Should I blend this out instead?
}
// Note: writes variables from skip list, bug?
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
// TODO: Should I blend this in instead?
if (skip.find((*it).first) == skip.end())
continue;
if (!settings.has((*it).first))
continue;
newSettings[(*it).first] = (*it).second;
}
return newSettings;
}
LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD &value, const LLSD &other_value, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const
{
LLSD new_value;
LLSD::Type setting_type = value.type();
if (other_value.type() != setting_type)
{
// The data type mismatched between this and other. Hard switch when we pass the break point
// but issue a warning.
LL_WARNS("SETTINGS") << "Setting lerp between mismatched types for '" << key_name << "'." << LL_ENDL;
new_value = (mix > BREAK_POINT) ? other_value : value;
}
switch (setting_type)
{
case LLSD::TypeInteger:
// lerp between the two values rounding the result to the nearest integer.
new_value = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix)));
break;
case LLSD::TypeReal:
// lerp between the two values.
new_value = LLSD::Real(lerp(value.asReal(), other_value.asReal(), mix));
break;
case LLSD::TypeMap:
// deep copy.
new_value = interpolateSDMap(value, other_value, defaults, mix);
break;
case LLSD::TypeArray:
{
LLSD new_array(LLSD::emptyArray());
if (slerps.find(key_name) != slerps.end())
{
LLQuaternion a(value);
LLQuaternion b(other_value);
LLQuaternion q = slerp(mix, a, b);
new_array = q.getValue();
}
else
{ // TODO: We could expand this to inspect the type and do a deep lerp based on type.
// for now assume a heterogeneous array of reals.
size_t len = std::max(value.size(), other_value.size());
for (size_t i = 0; i < len; ++i)
{
new_array[i] = lerp(value[i].asReal(), other_value[i].asReal(), mix);
}
}
new_value = new_array;
}
break;
case LLSD::TypeUUID:
new_value = value.asUUID();
break;
// case LLSD::TypeBoolean:
// case LLSD::TypeString:
// case LLSD::TypeURI:
// case LLSD::TypeBinary:
// case LLSD::TypeDate:
default:
// atomic or unknown data types. Lerping between them does not make sense so switch at the break.
new_value = (mix > BREAK_POINT) ? other_value : value;
break;
}
return new_value;
}
LLSettingsBase::stringset_t LLSettingsBase::getSkipInterpolateKeys() const
{
static stringset_t skipSet;
if (skipSet.empty())
{
skipSet.insert(SETTING_FLAGS);
skipSet.insert(SETTING_HASH);
}
return skipSet;
}
LLSD LLSettingsBase::getSettings() const
{
return mSettings;
}
LLSD LLSettingsBase::cloneSettings() const
{
return combineSDMaps(getSettings(), LLSD());
}
size_t LLSettingsBase::getHash() const
{ // get a shallow copy of the LLSD filtering out values to not include in the hash
LLSD hash_settings = llsd_shallow(getSettings(),
LLSDMap(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)("*", true));
boost::hash<LLSD> hasher;
return hasher(hash_settings);
}
bool LLSettingsBase::validate()
{
validation_list_t validations = getValidationList();
if (!mSettings.has(SETTING_TYPE))
{
mSettings[SETTING_TYPE] = getSettingsType();
}
LLSD result = LLSettingsBase::settingValidation(mSettings, validations);
if (result["errors"].size() > 0)
{
LL_WARNS("SETTINGS") << "Validation errors: " << result["errors"] << LL_ENDL;
}
if (result["warnings"].size() > 0)
{
LL_DEBUGS("SETTINGS") << "Validation warnings: " << result["warnings"] << LL_ENDL;
}
return result["success"].asBoolean();
}
LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &validations, bool partial)
{
static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, 32));
static Validator validateId(SETTING_ID, false, LLSD::TypeUUID);
static Validator validateHash(SETTING_HASH, false, LLSD::TypeInteger);
static Validator validateType(SETTING_TYPE, false, LLSD::TypeString);
static Validator validateAssetId(SETTING_ASSETID, false, LLSD::TypeUUID);
static Validator validateFlags(SETTING_FLAGS, false, LLSD::TypeInteger);
stringset_t validated;
stringset_t strip;
bool isValid(true);
LLSD errors(LLSD::emptyArray());
LLSD warnings(LLSD::emptyArray());
U32 flags(0);
if (partial)
flags |= Validator::VALIDATION_PARTIAL;
// Fields common to all settings.
if (!validateName.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'name'.") );
isValid = false;
}
validated.insert(validateName.getName());
if (!validateId.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'id'.") );
isValid = false;
}
validated.insert(validateId.getName());
if (!validateHash.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'hash'.") );
isValid = false;
}
validated.insert(validateHash.getName());
if (!validateAssetId.verify(settings, flags))
{
errors.append(LLSD::String("Invalid asset Id"));
isValid = false;
}
validated.insert(validateAssetId.getName());
if (!validateType.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'type'.") );
isValid = false;
}
validated.insert(validateType.getName());
if (!validateFlags.verify(settings, flags))
{
errors.append(LLSD::String("Unable to validate 'flags'."));
isValid = false;
}
validated.insert(validateFlags.getName());
// Fields for specific settings.
for (validation_list_t::iterator itv = validations.begin(); itv != validations.end(); ++itv)
{
#ifdef VALIDATION_DEBUG
LLSD oldvalue;
if (settings.has((*itv).getName()))
{
oldvalue = llsd_clone(mSettings[(*itv).getName()]);
}
#endif
if (!(*itv).verify(settings, flags))
{
std::stringstream errtext;
errtext << "Settings LLSD fails validation and could not be corrected for '" << (*itv).getName() << "'!\n";
errors.append( errtext.str() );
isValid = false;
}
validated.insert((*itv).getName());
#ifdef VALIDATION_DEBUG
if (!oldvalue.isUndefined())
{
if (!compare_llsd(settings[(*itv).getName()], oldvalue))
{
LL_WARNS("SETTINGS") << "Setting '" << (*itv).getName() << "' was changed: " << oldvalue << " -> " << settings[(*itv).getName()] << LL_ENDL;
}
}
#endif
}
// strip extra entries
for (LLSD::map_const_iterator itm = settings.beginMap(); itm != settings.endMap(); ++itm)
{
if (validated.find((*itm).first) == validated.end())
{
std::stringstream warntext;
warntext << "Stripping setting '" << (*itm).first << "'";
warnings.append( warntext.str() );
strip.insert((*itm).first);
}
}
for (stringset_t::iterator its = strip.begin(); its != strip.end(); ++its)
{
settings.erase(*its);
}
return LLSDMap("success", LLSD::Boolean(isValid))
("errors", errors)
("warnings", warnings);
}
//=========================================================================
bool LLSettingsBase::Validator::verify(LLSD &data, U32 flags)
{
if (!data.has(mName) || (data.has(mName) && data[mName].isUndefined()))
{
if ((flags & VALIDATION_PARTIAL) != 0) // we are doing a partial validation. Do no attempt to set a default if missing (or fail even if required)
return true;
if (!mDefault.isUndefined())
{
data[mName] = mDefault;
return true;
}
if (mRequired)
LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "' with no default." << LL_ENDL;
return !mRequired;
}
if (data[mName].type() != mType)
{
LL_WARNS("SETTINGS") << "Setting '" << mName << "' is incorrect type." << LL_ENDL;
return false;
}
if (!mVerify.empty() && !mVerify(data[mName]))
{
LL_WARNS("SETTINGS") << "Setting '" << mName << "' fails validation." << LL_ENDL;
return false;
}
return true;
}
bool LLSettingsBase::Validator::verifyColor(LLSD &value)
{
return (value.size() == 3 || value.size() == 4);
}
bool LLSettingsBase::Validator::verifyVector(LLSD &value, S32 length)
{
return (value.size() == length);
}
bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length)
{
if (value.size() != length)
return false;
LLSD newvector;
switch (length)
{
case 2:
{
LLVector2 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
case 3:
{
LLVector3 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
case 4:
{
LLVector4 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
default:
return false;
}
return true;
}
bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals)
{
for (S32 index = 0; index < value.size(); ++index)
{
if (minvals[index].asString() != "*")
{
if (minvals[index].asReal() > value[index].asReal())
{
value[index] = minvals[index].asReal();
}
}
if (maxvals[index].asString() != "*")
{
if (maxvals[index].asReal() < value[index].asReal())
{
value[index] = maxvals[index].asReal();
}
}
}
return true;
}
bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value)
{
return (value.size() == 4);
}
bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value)
{
if (value.size() != 4)
return false;
LLQuaternion quat(value);
if (is_approx_equal(quat.normalize(), 1.0f))
return true;
LLSD newquat = quat.getValue();
for (S32 index = 0; index < 4; ++index)
{
value[index] = newquat[index];
}
return true;
}
bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range)
{
F64 real = value.asReal();
F64 clampedval = llclamp(LLSD::Real(real), range[0].asReal(), range[1].asReal());
if (is_approx_equal(clampedval, real))
return true;
value = LLSD::Real(clampedval);
return true;
}
bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range)
{
S32 ival = value.asInteger();
S32 clampedval = llclamp(LLSD::Integer(ival), range[0].asInteger(), range[1].asInteger());
if (clampedval == ival)
return true;
value = LLSD::Integer(clampedval);
return true;
}
bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, S32 length)
{
std::string sval = value.asString();
if (!sval.empty())
{
sval = sval.substr(0, length);
value = LLSD::String(sval);
}
return true;
}
//=========================================================================
void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf)
{
F64 res = setBlendFactor(blendf);
if ((res >= 0.0001) && (res < 1.0))
mTarget->update();
}
F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_in)
{
LLSettingsBase::TrackPosition blendf = blendf_in;
if (blendf >= 1.0)
{
triggerComplete();
return 1.0;
}
blendf = llclamp(blendf, 0.0f, 1.0f);
if (mTarget)
{
mTarget->replaceSettings(mInitial->getSettings());
if (!mFinal || (mInitial == mFinal) || (blendf == 0.0))
{ // this is a trivial blend. Results will be identical to the initial.
return blendf;
}
mTarget->blend(mFinal, blendf);
}
else
{
LL_WARNS("SETTINGS") << "No target for settings blender." << LL_ENDL;
}
return blendf;
}
void LLSettingsBlender::triggerComplete()
{
if (mTarget)
mTarget->replaceSettings(mFinal->getSettings());
LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon
mTarget->update();
mOnFinished(shared_from_this());
}
//-------------------------------------------------------------------------
const LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::MIN_BLEND_DELTA(0.001);
LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const
{
return LLSettingsBase::BlendFactor(fmod((F64)spanpos, (F64)spanlen) / (F64)spanlen);
}
bool LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& timedelta)
{
mTimeSpent += timedelta;
mTimeDeltaPassed += timedelta;
if (mTimeSpent > mBlendSpan)
{
mIgnoreTimeDelta = false;
triggerComplete();
return false;
}
if ((mTimeDeltaPassed < mTimeDeltaThreshold) && (!mIgnoreTimeDelta))
{
return false;
}
LLSettingsBase::BlendFactor blendf = calculateBlend(mTimeSpent, mBlendSpan);
mTimeDeltaPassed = LLSettingsBase::Seconds(0.0);
if (fabs(mLastBlendF - blendf) < mBlendFMinDelta)
{
return false;
}
mLastBlendF = blendf;
update(blendf);
return true;
}

View File

@@ -0,0 +1,538 @@
/**
* @file llsettingsbase.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_SETTINGS_BASE_H
#define LL_SETTINGS_BASE_H
#include <string>
#include <map>
#include <vector>
#include <boost/signals2.hpp>
#include "llsd.h"
#include "llsdutil.h"
#include "v2math.h"
#include "v3math.h"
#include "v4math.h"
#include "llquaternion.h"
#include "v4color.h"
#include "v3color.h"
#include "llunits.h"
#include "llinventorysettings.h"
#define PTR_NAMESPACE std
#define SETTINGS_OVERRIDE override
class LLSettingsBase :
public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBase>,
private boost::noncopyable
{
friend class LLEnvironment;
friend class LLSettingsDay;
friend std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings);
protected:
LOG_CLASS(LLSettingsBase);
public:
typedef F64Seconds Seconds;
typedef F64 BlendFactor;
typedef F32 TrackPosition; // 32-bit as these are stored in LLSD as such
static const TrackPosition INVALID_TRACKPOS;
static const std::string SETTING_ID;
static const std::string SETTING_NAME;
static const std::string SETTING_HASH;
static const std::string SETTING_TYPE;
static const std::string SETTING_ASSETID;
static const std::string SETTING_FLAGS;
static const U32 FLAG_NOCOPY;
static const U32 FLAG_NOMOD;
static const U32 FLAG_NOTRANS;
class DefaultParam
{
public:
DefaultParam(S32 key, const LLSD& value) : mShaderKey(key), mDefaultValue(value) {}
DefaultParam() : mShaderKey(-1) {}
S32 getShaderKey() const { return mShaderKey; }
const LLSD getDefaultValue() const { return mDefaultValue; }
private:
S32 mShaderKey;
LLSD mDefaultValue;
};
// Contains settings' names (map key), related shader id-key and default
// value for revert in case we need to reset shader (no need to search each time)
typedef std::map<std::string, DefaultParam> parammapping_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsBase> ptr_t;
virtual ~LLSettingsBase() { };
//---------------------------------------------------------------------
virtual std::string getSettingsType() const = 0;
virtual LLSettingsType::type_e getSettingsTypeValue() const = 0;
//---------------------------------------------------------------------
// Settings status
inline bool hasSetting(const std::string &param) const { return mSettings.has(param); }
virtual bool isDirty() const { return mDirty; }
virtual bool isVeryDirty() const { return mReplaced; }
inline void setDirtyFlag(bool dirty) { mDirty = dirty; clearAssetId(); }
size_t getHash() const; // Hash will not include Name, ID or a previously stored Hash
inline LLUUID getId() const
{
return getValue(SETTING_ID).asUUID();
}
inline std::string getName() const
{
return getValue(SETTING_NAME).asString();
}
inline void setName(std::string val)
{
setValue(SETTING_NAME, val);
}
inline LLUUID getAssetId() const
{
if (mSettings.has(SETTING_ASSETID))
return mSettings[SETTING_ASSETID].asUUID();
return LLUUID();
}
inline U32 getFlags() const
{
if (mSettings.has(SETTING_FLAGS))
return static_cast<U32>(mSettings[SETTING_FLAGS].asInteger());
return 0;
}
inline void setFlags(U32 value)
{
setLLSD(SETTING_FLAGS, LLSD::Integer(value));
}
inline bool getFlag(U32 flag) const
{
if (mSettings.has(SETTING_FLAGS))
return ((U32)mSettings[SETTING_FLAGS].asInteger() & flag) == flag;
return false;
}
inline void setFlag(U32 flag)
{
U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0);
flags |= flag;
if (flags)
mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
else
mSettings.erase(SETTING_FLAGS);
}
inline void clearFlag(U32 flag)
{
U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0);
flags &= ~flag;
if (flags)
mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
else
mSettings.erase(SETTING_FLAGS);
}
virtual void replaceSettings(LLSD settings)
{
mBlendedFactor = 0.0;
setDirtyFlag(true);
mReplaced = true;
mSettings = settings;
}
virtual LLSD getSettings() const;
//---------------------------------------------------------------------
//
inline void setLLSD(const std::string &name, const LLSD &value)
{
mSettings[name] = value;
mDirty = true;
if (name != SETTING_ASSETID)
clearAssetId();
}
inline void setValue(const std::string &name, const LLSD &value)
{
setLLSD(name, value);
}
inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD()) const
{
if (!mSettings.has(name))
return deflt;
return mSettings[name];
}
inline void setValue(const std::string &name, F32 v)
{
setLLSD(name, LLSD::Real(v));
}
inline void setValue(const std::string &name, const LLVector2 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLVector3 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLVector4 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLQuaternion &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLColor3 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLColor4 &value)
{
setValue(name, value.getValue());
}
inline BlendFactor getBlendFactor() const
{
return mBlendedFactor;
}
// Note this method is marked const but may modify the settings object.
// (note the internal const cast). This is so that it may be called without
// special consideration from getters.
inline void update() const
{
if ((!mDirty) && (!mReplaced))
return;
(const_cast<LLSettingsBase *>(this))->updateSettings();
}
virtual void blend(const ptr_t &end, BlendFactor blendf) = 0;
virtual bool validate();
virtual ptr_t buildDerivedClone() const = 0;
class Validator
{
public:
static const U32 VALIDATION_PARTIAL;
typedef boost::function<bool(LLSD &)> verify_pr;
Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr(), LLSD defval = LLSD()) :
mName(name),
mRequired(required),
mType(type),
mVerify(verify),
mDefault(defval)
{ }
std::string getName() const { return mName; }
bool isRequired() const { return mRequired; }
LLSD::Type getType() const { return mType; }
bool verify(LLSD &data, U32 flags);
// Some basic verifications
static bool verifyColor(LLSD &value);
static bool verifyVector(LLSD &value, S32 length);
static bool verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals);
static bool verifyVectorNormalized(LLSD &value, S32 length);
static bool verifyQuaternion(LLSD &value);
static bool verifyQuaternionNormal(LLSD &value);
static bool verifyFloatRange(LLSD &value, LLSD range);
static bool verifyIntegerRange(LLSD &value, LLSD range);
static bool verifyStringLength(LLSD &value, S32 length);
private:
std::string mName;
bool mRequired;
LLSD::Type mType;
verify_pr mVerify;
LLSD mDefault;
};
typedef std::vector<Validator> validation_list_t;
static LLSD settingValidation(LLSD &settings, validation_list_t &validations, bool partial = false);
inline void setAssetId(LLUUID value)
{ // note that this skips setLLSD
mSettings[SETTING_ASSETID] = value;
}
inline void clearAssetId()
{
if (mSettings.has(SETTING_ASSETID))
mSettings.erase(SETTING_ASSETID);
}
// Calculate any custom settings that may need to be cached.
virtual void updateSettings() { mDirty = false; mReplaced = false; }
protected:
LLSettingsBase();
LLSettingsBase(const LLSD setting);
static LLSD settingValidation(LLSD settings);
typedef std::set<std::string> stringset_t;
// combining settings objects. Customize for specific setting types
virtual void lerpSettings(const LLSettingsBase &other, BlendFactor mix);
// combining settings maps where it can based on mix rate
// @settings initial value (mix==0)
// @other target value (mix==1)
// @defaults list of default values for legacy fields and (re)setting shaders
// @mix from 0 to 1, ratio or rate of transition from initial 'settings' to 'other'
// return interpolated and combined LLSD map
LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, BlendFactor mix) const;
LLSD interpolateSDValue(const std::string& name, const LLSD &value, const LLSD &other, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const;
/// when lerping between settings, some may require special handling.
/// Get a list of these key to be skipped by the default settings lerp.
/// (handling should be performed in the override of lerpSettings.
virtual stringset_t getSkipInterpolateKeys() const;
// A list of settings that represent quaternions and should be slerped
// rather than lerped.
virtual stringset_t getSlerpKeys() const { return stringset_t(); }
virtual validation_list_t getValidationList() const = 0;
// Apply any settings that need special handling.
virtual void applySpecial(void *) { };
virtual parammapping_t getParameterMap() const { return parammapping_t(); }
LLSD mSettings;
bool mIsValid;
LLAssetID mAssetID;
LLSD cloneSettings() const;
inline void setBlendFactor(BlendFactor blendfactor)
{
mBlendedFactor = blendfactor;
}
void replaceWith(LLSettingsBase::ptr_t other)
{
replaceSettings(other->cloneSettings());
setBlendFactor(other->getBlendFactor());
}
private:
bool mDirty;
bool mReplaced; // super dirty!
LLSD combineSDMaps(const LLSD &first, const LLSD &other) const;
BlendFactor mBlendedFactor;
};
class LLSettingsBlender : public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBlender>
{
LOG_CLASS(LLSettingsBlender);
public:
typedef PTR_NAMESPACE::shared_ptr<LLSettingsBlender> ptr_t;
typedef boost::signals2::signal<void(const ptr_t )> finish_signal_t;
typedef boost::signals2::connection connection_t;
LLSettingsBlender(const LLSettingsBase::ptr_t &target,
const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting) :
mOnFinished(),
mTarget(target),
mInitial(initsetting),
mFinal(endsetting)
{
if (mInitial && mTarget)
mTarget->replaceSettings(mInitial->getSettings());
if (!mFinal)
mFinal = mInitial;
}
virtual ~LLSettingsBlender() {}
virtual void reset( LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::TrackPosition&)
{
// note: the 'span' reset parameter is unused by the base class.
if (!mInitial)
LL_WARNS("BLENDER") << "Reseting blender with empty initial setting. Expect badness in the future." << LL_ENDL;
mInitial = initsetting;
mFinal = endsetting;
if (!mFinal)
mFinal = mInitial;
if (mTarget)
mTarget->replaceSettings(mInitial->getSettings());
}
LLSettingsBase::ptr_t getTarget() const
{
return mTarget;
}
LLSettingsBase::ptr_t getInitial() const
{
return mInitial;
}
LLSettingsBase::ptr_t getFinal() const
{
return mFinal;
}
connection_t setOnFinished(const finish_signal_t::slot_type &onfinished)
{
return mOnFinished.connect(onfinished);
}
virtual void update(const LLSettingsBase::BlendFactor& blendf);
virtual bool applyTimeDelta(const LLSettingsBase::Seconds& timedelta)
{
llassert(false);
// your derived class needs to implement an override of this func
return false;
}
virtual F64 setBlendFactor(const LLSettingsBase::BlendFactor& position);
virtual void switchTrack(S32 trackno, const LLSettingsBase::TrackPosition& position) { /*NoOp*/ }
protected:
void triggerComplete();
finish_signal_t mOnFinished;
LLSettingsBase::ptr_t mTarget;
LLSettingsBase::ptr_t mInitial;
LLSettingsBase::ptr_t mFinal;
};
class LLSettingsBlenderTimeDelta : public LLSettingsBlender
{
LOG_CLASS(LLSettingsBlenderTimeDelta);
public:
static const LLSettingsBase::BlendFactor MIN_BLEND_DELTA;
LLSettingsBlenderTimeDelta(const LLSettingsBase::ptr_t &target,
const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::Seconds& blend_span) :
LLSettingsBlender(target, initsetting, endsetting),
mBlendSpan(blend_span),
mLastUpdate(0.0f),
mTimeSpent(0.0f),
mTimeDeltaThreshold(0.0f),
mTimeDeltaPassed(0.0f),
mIgnoreTimeDelta(false),
mBlendFMinDelta(MIN_BLEND_DELTA),
mLastBlendF(-1.0f)
{
mTimeStart = LLSettingsBase::Seconds(LLDate::now().secondsSinceEpoch());
mLastUpdate = mTimeStart;
}
virtual ~LLSettingsBlenderTimeDelta()
{
}
virtual void reset(LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::TrackPosition& blend_span) SETTINGS_OVERRIDE
{
LLSettingsBlender::reset(initsetting, endsetting, blend_span);
mBlendSpan = blend_span;
mTimeStart = LLSettingsBase::Seconds(LLDate::now().secondsSinceEpoch());
mLastUpdate = mTimeStart;
mTimeSpent = LLSettingsBase::Seconds(0.0f);
mTimeDeltaPassed = LLSettingsBase::Seconds(0.0f);
mLastBlendF = LLSettingsBase::BlendFactor(-1.0f);
}
virtual bool applyTimeDelta(const LLSettingsBase::Seconds& timedelta) SETTINGS_OVERRIDE;
inline void setTimeDeltaThreshold(const LLSettingsBase::Seconds time)
{
mTimeDeltaThreshold = time;
mTimeDeltaPassed = time + LLSettingsBase::Seconds(1.0); // take the next update call.
}
inline LLSettingsBase::Seconds getTimeDeltaThreshold() const
{
return mTimeDeltaThreshold;
}
inline void setIgnoreTimeDeltaThreshold(bool val) { mIgnoreTimeDelta = val; }
inline bool getIgnoreTimeDeltaThreshold() const { return mIgnoreTimeDelta; }
inline void setTimeSpent(LLSettingsBase::Seconds time) { mTimeSpent = time; }
protected:
LLSettingsBase::BlendFactor calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const;
LLSettingsBase::TrackPosition mBlendSpan;
LLSettingsBase::Seconds mLastUpdate;
LLSettingsBase::Seconds mTimeSpent;
LLSettingsBase::Seconds mTimeStart;
LLSettingsBase::Seconds mTimeDeltaThreshold;
LLSettingsBase::Seconds mTimeDeltaPassed;
bool mIgnoreTimeDelta;
LLSettingsBase::BlendFactor mBlendFMinDelta;
LLSettingsBase::BlendFactor mLastBlendF;
};
#endif

View File

@@ -0,0 +1,891 @@
/**
* @file llsettingsdaycycle.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llsettingsdaycycle.h"
#include "llerror.h"
#include <algorithm>
#include <boost/make_shared.hpp>
#include "llfasttimer.h"
#include "v3colorutil.h"
#include "llsettingssky.h"
#include "llsettingswater.h"
#include "llframetimer.h"
//=========================================================================
namespace
{
LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
template<typename T>
inline T get_wrapping_distance(T begin, T end)
{
if (begin < end)
{
return end - begin;
}
else if (begin > end)
{
return T(1.0) - (begin - end);
}
return 0;
}
LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
{
if (collection.empty())
return collection.end();
LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key);
if (it == collection.end())
{ // wrap around
it = collection.begin();
}
return it;
}
LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
{
if (collection.empty())
return collection.end();
LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key);
if (it == collection.end())
{ // all keyframes are lower, take the last one.
--it; // we know the range is not empty
}
else if ((*it).first > key)
{ // the keyframe we are interested in is smaller than the found.
if (it == collection.begin())
it = collection.end();
--it;
}
return it;
}
}
//=========================================================================
const std::string LLSettingsDay::SETTING_KEYID("key_id");
const std::string LLSettingsDay::SETTING_KEYNAME("key_name");
const std::string LLSettingsDay::SETTING_KEYKFRAME("key_keyframe");
const std::string LLSettingsDay::SETTING_KEYHASH("key_hash");
const std::string LLSettingsDay::SETTING_TRACKS("tracks");
const std::string LLSettingsDay::SETTING_FRAMES("frames");
const LLSettingsDay::Seconds LLSettingsDay::MINIMUM_DAYLENGTH(14400); // 4 hours
const LLSettingsDay::Seconds LLSettingsDay::DEFAULT_DAYLENGTH(14400); // 4 hours
const LLSettingsDay::Seconds LLSettingsDay::MAXIMUM_DAYLENGTH(604800); // 7 days
const LLSettingsDay::Seconds LLSettingsDay::MINIMUM_DAYOFFSET(0);
const LLSettingsDay::Seconds LLSettingsDay::DEFAULT_DAYOFFSET(57600); // +16 hours == -8 hours (SLT time offset)
const LLSettingsDay::Seconds LLSettingsDay::MAXIMUM_DAYOFFSET(86400); // 24 hours
const S32 LLSettingsDay::TRACK_WATER(0); // water track is 0
const S32 LLSettingsDay::TRACK_GROUND_LEVEL(1);
const S32 LLSettingsDay::TRACK_MAX(5); // 5 tracks, 4 skys, 1 water
const S32 LLSettingsDay::FRAME_MAX(56);
const F32 LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR(0.02501f);
const LLUUID LLSettingsDay::DEFAULT_ASSET_ID("78751d18-6c51-3c43-2887-3654cd427a42");
// Minimum value to prevent multislider in edit floaters from eating up frames that 'encroach' on one another's space
static const F32 DEFAULT_MULTISLIDER_INCREMENT(0.005f);
//=========================================================================
LLSettingsDay::LLSettingsDay(const LLSD &data) :
LLSettingsBase(data),
mInitialized(false)
{
mDayTracks.resize(TRACK_MAX);
}
LLSettingsDay::LLSettingsDay() :
LLSettingsBase(),
mInitialized(false)
{
mDayTracks.resize(TRACK_MAX);
}
//=========================================================================
LLSD LLSettingsDay::getSettings() const
{
LLSD settings(LLSD::emptyMap());
if (mSettings.has(SETTING_NAME))
settings[SETTING_NAME] = mSettings[SETTING_NAME];
if (mSettings.has(SETTING_ID))
settings[SETTING_ID] = mSettings[SETTING_ID];
if (mSettings.has(SETTING_ASSETID))
settings[SETTING_ASSETID] = mSettings[SETTING_ASSETID];
settings[SETTING_TYPE] = getSettingsType();
std::map<std::string, LLSettingsBase::ptr_t> in_use;
LLSD tracks(LLSD::emptyArray());
for (CycleList_t::const_iterator itTrack = mDayTracks.begin(); itTrack != mDayTracks.end(); ++itTrack)
{
LLSD trackout(LLSD::emptyArray());
for (CycleTrack_t::const_iterator itFrame = (*itTrack).begin(); itFrame != (*itTrack).end(); ++itFrame)
{
F32 frame = (*itFrame).first;
LLSettingsBase::ptr_t data = (*itFrame).second;
size_t datahash = data->getHash();
std::stringstream keyname;
keyname << datahash;
trackout.append(LLSD(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(frame))(SETTING_KEYNAME, keyname.str())));
in_use[keyname.str()] = data;
}
tracks.append(trackout);
}
settings[SETTING_TRACKS] = tracks;
LLSD frames(LLSD::emptyMap());
for (std::map<std::string, LLSettingsBase::ptr_t>::iterator itFrame = in_use.begin(); itFrame != in_use.end(); ++itFrame)
{
LLSD framesettings = llsd_clone((*itFrame).second->getSettings(),
LLSDMap("*", true)(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false));
frames[(*itFrame).first] = framesettings;
}
settings[SETTING_FRAMES] = frames;
return settings;
}
bool LLSettingsDay::initialize(bool validate_frames)
{
LLSD tracks = mSettings[SETTING_TRACKS];
LLSD frames = mSettings[SETTING_FRAMES];
// save for later...
LLUUID assetid;
if (mSettings.has(SETTING_ASSETID))
{
assetid = mSettings[SETTING_ASSETID].asUUID();
}
std::map<std::string, LLSettingsBase::ptr_t> used;
for (LLSD::map_const_iterator itFrame = frames.beginMap(); itFrame != frames.endMap(); ++itFrame)
{
std::string name = (*itFrame).first;
LLSD data = (*itFrame).second;
LLSettingsBase::ptr_t keyframe;
if (data[SETTING_TYPE].asString() == "sky")
{
keyframe = buildSky(data);
}
else if (data[SETTING_TYPE].asString() == "water")
{
keyframe = buildWater(data);
}
else
{
LL_WARNS("DAYCYCLE") << "Unknown child setting type '" << data[SETTING_TYPE].asString() << "' named '" << name << "'" << LL_ENDL;
}
if (!keyframe)
{
LL_WARNS("DAYCYCLE") << "Invalid frame data" << LL_ENDL;
continue;
}
used[name] = keyframe;
}
bool haswater(false);
bool hassky(false);
for (S32 i = 0; (i < tracks.size()) && (i < TRACK_MAX); ++i)
{
mDayTracks[i].clear();
LLSD curtrack = tracks[i];
for (LLSD::array_const_iterator it = curtrack.beginArray(); it != curtrack.endArray(); ++it)
{
LLSettingsBase::TrackPosition keyframe = LLSettingsBase::TrackPosition((*it)[SETTING_KEYKFRAME].asReal());
keyframe = llclamp(keyframe, 0.0f, 1.0f);
LLSettingsBase::ptr_t setting;
if ((*it).has(SETTING_KEYNAME))
{
std::string key_name = (*it)[SETTING_KEYNAME];
if (i == TRACK_WATER)
{
setting = used[key_name];
if (setting && setting->getSettingsType() != "water")
{
LL_WARNS("DAYCYCLE") << "Water track referencing " << setting->getSettingsType() << " frame at " << keyframe << "." << LL_ENDL;
setting.reset();
}
}
else
{
setting = used[key_name];
if (setting && setting->getSettingsType() != "sky")
{
LL_WARNS("DAYCYCLE") << "Sky track #" << i << " referencing " << setting->getSettingsType() << " frame at " << keyframe << "." << LL_ENDL;
setting.reset();
}
}
}
if (setting)
{
if (i == TRACK_WATER)
haswater |= true;
else
hassky |= true;
if (validate_frames && mDayTracks[i].size() > 0)
{
// check if we hit close to anything in the list
LLSettingsDay::CycleTrack_t::value_type frame = getSettingsNearKeyframe(keyframe, i, DEFAULT_FRAME_SLOP_FACTOR);
if (frame.second)
{
// figure out direction of search
LLSettingsBase::TrackPosition found = frame.first;
LLSettingsBase::TrackPosition new_frame = keyframe;
F32 total_frame_shift = 0;
// We consider frame DEFAULT_FRAME_SLOP_FACTOR away as still encroaching, so add minimum increment
F32 move_factor = DEFAULT_FRAME_SLOP_FACTOR + DEFAULT_MULTISLIDER_INCREMENT;
bool move_forward = true;
if ((new_frame < found && (found - new_frame) <= DEFAULT_FRAME_SLOP_FACTOR)
|| (new_frame > found && (new_frame - found) > DEFAULT_FRAME_SLOP_FACTOR))
{
move_forward = false;
}
if (move_forward)
{
CycleTrack_t::iterator iter = mDayTracks[i].find(found);
new_frame = found; // for total_frame_shift
while (total_frame_shift < 1)
{
// calculate shifted position from previous found point
total_frame_shift += move_factor + (found >= new_frame ? found : found + 1) - new_frame;
new_frame = found + move_factor;
if (new_frame > 1) new_frame--;
// we know that current point is too close, go for next one
iter++;
if (iter == mDayTracks[i].end())
{
iter = mDayTracks[i].begin();
}
if (((iter->first >= (new_frame - DEFAULT_MULTISLIDER_INCREMENT)) && ((new_frame + DEFAULT_FRAME_SLOP_FACTOR) >= iter->first))
|| ((iter->first < new_frame) && ((new_frame + DEFAULT_FRAME_SLOP_FACTOR) >= (iter->first + 1))))
{
// we are encroaching at new point as well
found = iter->first;
}
else // (new_frame + DEFAULT_FRAME_SLOP_FACTOR < iter->first)
{
//we found clear spot
break;
}
}
}
else
{
CycleTrack_t::reverse_iterator iter = mDayTracks[i].rbegin();
while (iter->first != found)
{
iter++;
}
new_frame = found; // for total_frame_shift
while (total_frame_shift < 1)
{
// calculate shifted position from current found point
total_frame_shift += move_factor + new_frame - (found <= new_frame ? found : found - 1);
new_frame = found - move_factor;
if (new_frame < 0) new_frame++;
// we know that current point is too close, go for next one
iter++;
if (iter == mDayTracks[i].rend())
{
iter = mDayTracks[i].rbegin();
}
if ((iter->first <= (new_frame + DEFAULT_MULTISLIDER_INCREMENT) && (new_frame - DEFAULT_FRAME_SLOP_FACTOR) <= iter->first)
|| ((iter->first > new_frame) && ((new_frame - DEFAULT_FRAME_SLOP_FACTOR) <= (iter->first - 1))))
{
// we are encroaching at new point as well
found = iter->first;
}
else // (new_frame - DEFAULT_FRAME_SLOP_FACTOR > iter->first)
{
//we found clear spot
break;
}
}
}
if (total_frame_shift >= 1)
{
LL_WARNS("SETTINGS") << "Could not fix frame position, adding as is to position: " << keyframe << LL_ENDL;
}
else
{
// Mark as new position
keyframe = new_frame;
}
}
}
mDayTracks[i][keyframe] = setting;
}
}
}
if (!haswater || !hassky)
{
LL_WARNS("DAYCYCLE") << "Must have at least one water and one sky frame!" << LL_ENDL;
return false;
}
// these are no longer needed and just take up space now.
mSettings.erase(SETTING_TRACKS);
mSettings.erase(SETTING_FRAMES);
if (!assetid.isNull())
{
mSettings[SETTING_ASSETID] = assetid;
}
mInitialized = true;
return true;
}
//=========================================================================
LLSD LLSettingsDay::defaults()
{
static LLSD dfltsetting;
if (dfltsetting.size() == 0)
{
dfltsetting[SETTING_NAME] = "_default_";
dfltsetting[SETTING_TYPE] = "daycycle";
LLSD frames(LLSD::emptyMap());
LLSD waterTrack;
LLSD skyTrack;
const U32 FRAME_COUNT = 8;
const F32 FRAME_STEP = 1.0f / F32(FRAME_COUNT);
F32 time = 0.0f;
for (U32 i = 0; i < FRAME_COUNT; i++)
{
std::string name("_default_");
name += ('a' + i);
std::string water_frame_name("water:");
std::string sky_frame_name("sky:");
water_frame_name += name;
sky_frame_name += name;
waterTrack[SETTING_KEYKFRAME] = time;
waterTrack[SETTING_KEYNAME] = water_frame_name;
skyTrack[SETTING_KEYKFRAME] = time;
skyTrack[SETTING_KEYNAME] = sky_frame_name;
frames[water_frame_name] = LLSettingsWater::defaults(time);
frames[sky_frame_name] = LLSettingsSky::defaults(time);
time += FRAME_STEP;
}
LLSD tracks;
tracks.append(LLSDArray(waterTrack));
tracks.append(LLSDArray(skyTrack));
dfltsetting[SETTING_TRACKS] = tracks;
dfltsetting[SETTING_FRAMES] = frames;
}
return dfltsetting;
}
void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F64 mix)
{
LL_ERRS("DAYCYCLE") << "Day cycles are not blendable!" << LL_ENDL;
}
namespace
{
bool validateDayCycleTrack(LLSD &value)
{
// Trim extra tracks.
while (value.size() > LLSettingsDay::TRACK_MAX)
{
value.erase(value.size() - 1);
}
S32 framecount(0);
for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track)
{
S32 index = 0;
while (index < (*track).size())
{
LLSD& elem = (*track)[index];
++framecount;
if (index >= LLSettingsDay::FRAME_MAX)
{
(*track).erase(index);
continue;
}
if (!elem.has(LLSettingsDay::SETTING_KEYKFRAME))
{
(*track).erase(index);
continue;
}
if (!elem[LLSettingsDay::SETTING_KEYKFRAME].isReal())
{
(*track).erase(index);
continue;
}
if (!elem.has(LLSettingsDay::SETTING_KEYNAME) &&
!elem.has(LLSettingsDay::SETTING_KEYID))
{
(*track).erase(index);
continue;
}
LLSettingsBase::TrackPosition frame = elem[LLSettingsDay::SETTING_KEYKFRAME].asReal();
if ((frame < 0.0) || (frame > 1.0))
{
frame = llclamp(frame, 0.0f, 1.0f);
elem[LLSettingsDay::SETTING_KEYKFRAME] = frame;
}
++index;
}
}
int waterTracks = value[0].size();
int skyTracks = framecount - waterTracks;
if (waterTracks < 1)
{
LL_WARNS("SETTINGS") << "Missing water track" << LL_ENDL;
return false;
}
if (skyTracks < 1)
{
LL_WARNS("SETTINGS") << "Missing sky tracks" << LL_ENDL;
return false;
}
return true;
}
bool validateDayCycleFrames(LLSD &value)
{
bool hasSky(false);
bool hasWater(false);
for (LLSD::map_iterator itf = value.beginMap(); itf != value.endMap(); ++itf)
{
LLSD frame = (*itf).second;
std::string ftype = frame[LLSettingsBase::SETTING_TYPE];
if (ftype == "sky")
{
LLSettingsSky::validation_list_t valid_sky = LLSettingsSky::validationList();
LLSD res_sky = LLSettingsBase::settingValidation(frame, valid_sky);
if (res_sky["success"].asInteger() == 0)
{
LL_WARNS("SETTINGS") << "Sky setting named '" << (*itf).first << "' validation failed!: " << res_sky << LL_ENDL;
LL_WARNS("SETTINGS") << "Sky: " << frame << LL_ENDL;
continue;
}
hasSky |= true;
}
else if (ftype == "water")
{
LLSettingsWater::validation_list_t valid_h2o = LLSettingsWater::validationList();
LLSD res_h2o = LLSettingsBase::settingValidation(frame, valid_h2o);
if (res_h2o["success"].asInteger() == 0)
{
LL_WARNS("SETTINGS") << "Water setting named '" << (*itf).first << "' validation failed!: " << res_h2o << LL_ENDL;
LL_WARNS("SETTINGS") << "Water: " << frame << LL_ENDL;
continue;
}
hasWater |= true;
}
else
{
LL_WARNS("SETTINGS") << "Unknown settings block of type '" << ftype << "' named '" << (*itf).first << "'" << LL_ENDL;
return false;
}
}
if (!hasSky)
{
LL_WARNS("SETTINGS") << "No skies defined." << LL_ENDL;
return false;
}
if (!hasWater)
{
LL_WARNS("SETTINGS") << "No waters defined." << LL_ENDL;
return false;
}
return true;
}
}
LLSettingsDay::validation_list_t LLSettingsDay::getValidationList() const
{
return LLSettingsDay::validationList();
}
LLSettingsDay::validation_list_t LLSettingsDay::validationList()
{
static validation_list_t validation;
if (validation.empty())
{
validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray,
&validateDayCycleTrack));
validation.push_back(Validator(SETTING_FRAMES, true, LLSD::TypeMap,
&validateDayCycleFrames));
}
return validation;
}
LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrack(S32 track)
{
static CycleTrack_t emptyTrack;
if (mDayTracks.size() <= track)
return emptyTrack;
return mDayTracks[track];
}
const LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrackConst(S32 track) const
{
static CycleTrack_t emptyTrack;
if (mDayTracks.size() <= track)
return emptyTrack;
return mDayTracks[track];
}
bool LLSettingsDay::clearCycleTrack(S32 track)
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to clear track (#" << track << ") out of range!" << LL_ENDL;
return false;
}
mDayTracks[track].clear();
clearAssetId();
setDirtyFlag(true);
return true;
}
bool LLSettingsDay::replaceCycleTrack(S32 track, const CycleTrack_t &source)
{
if (source.empty())
{
LL_WARNS("DAYCYCLE") << "Attempt to copy an empty track." << LL_ENDL;
return false;
}
{
LLSettingsBase::ptr_t first((*source.begin()).second);
std::string setting_type = first->getSettingsType();
if (((setting_type == "water") && (track != 0)) ||
((setting_type == "sky") && (track == 0)))
{
LL_WARNS("DAYCYCLE") << "Attempt to copy track missmatch" << LL_ENDL;
return false;
}
}
if (!clearCycleTrack(track))
return false;
mDayTracks[track] = source;
return true;
}
bool LLSettingsDay::isTrackEmpty(S32 track) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to test track (#" << track << ") out of range!" << LL_ENDL;
return true;
}
return mDayTracks[track].empty();
}
//=========================================================================
void LLSettingsDay::startDayCycle()
{
if (!mInitialized)
{
LL_WARNS("DAYCYCLE") << "Attempt to start day cycle on uninitialized object." << LL_ENDL;
return;
}
}
void LLSettingsDay::updateSettings()
{
}
//=========================================================================
LLSettingsDay::KeyframeList_t LLSettingsDay::getTrackKeyframes(S32 trackno)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return KeyframeList_t();
}
KeyframeList_t keyframes;
CycleTrack_t &track = mDayTracks[trackno];
keyframes.reserve(track.size());
for (CycleTrack_t::iterator it = track.begin(); it != track.end(); ++it)
{
keyframes.push_back((*it).first);
}
return keyframes;
}
bool LLSettingsDay::moveTrackKeyframe(S32 trackno, const LLSettingsBase::TrackPosition& old_frame, const LLSettingsBase::TrackPosition& new_frame)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return false;
}
if (old_frame == new_frame)
{
return false;
}
CycleTrack_t &track = mDayTracks[trackno];
CycleTrack_t::iterator iter = track.find(old_frame);
if (iter != track.end())
{
LLSettingsBase::ptr_t base = iter->second;
track.erase(iter);
track[llclamp(new_frame, 0.0f, 1.0f)] = base;
track[new_frame] = base;
return true;
}
return false;
}
bool LLSettingsDay::removeTrackKeyframe(S32 trackno, const LLSettingsBase::TrackPosition& frame)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return false;
}
CycleTrack_t &track = mDayTracks[trackno];
CycleTrack_t::iterator iter = track.find(frame);
if (iter != track.end())
{
LLSettingsBase::ptr_t base = iter->second;
track.erase(iter);
return true;
}
return false;
}
void LLSettingsDay::setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, const LLSettingsBase::TrackPosition& keyframe)
{
setSettingsAtKeyframe(water, keyframe, TRACK_WATER);
}
LLSettingsWater::ptr_t LLSettingsDay::getWaterAtKeyframe(const LLSettingsBase::TrackPosition& keyframe) const
{
LLSettingsBase* p = getSettingsAtKeyframe(keyframe, TRACK_WATER).get();
return LLSettingsWater::ptr_t((LLSettingsWater*)p);
}
void LLSettingsDay::setSkyAtKeyframe(const LLSettingsSky::ptr_t &sky, const LLSettingsBase::TrackPosition& keyframe, S32 track)
{
if ((track < 1) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return;
}
setSettingsAtKeyframe(sky, keyframe, track);
}
LLSettingsSky::ptr_t LLSettingsDay::getSkyAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const
{
if ((track < 1) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return LLSettingsSky::ptr_t();
}
return PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(getSettingsAtKeyframe(keyframe, track));
}
void LLSettingsDay::setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, const LLSettingsBase::TrackPosition& keyframe, S32 track)
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set track (#" << track << ") out of range!" << LL_ENDL;
return;
}
std::string type = settings->getSettingsType();
if ((track == TRACK_WATER) && (type != "water"))
{
LL_WARNS("DAYCYCLE") << "Attempt to add frame of type '" << type << "' to water track!" << LL_ENDL;
llassert(type == "water");
return;
}
else if ((track != TRACK_WATER) && (type != "sky"))
{
LL_WARNS("DAYCYCLE") << "Attempt to add frame of type '" << type << "' to sky track!" << LL_ENDL;
llassert(type == "sky");
return;
}
mDayTracks[track][llclamp(keyframe, 0.0f, 1.0f)] = settings;
setDirtyFlag(true);
}
LLSettingsBase::ptr_t LLSettingsDay::getSettingsAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return LLSettingsBase::ptr_t();
}
// todo: better way to identify keyframes?
CycleTrack_t::const_iterator iter = mDayTracks[track].find(keyframe);
if (iter != mDayTracks[track].end())
{
return iter->second;
}
return LLSettingsBase::ptr_t();
}
LLSettingsDay::CycleTrack_t::value_type LLSettingsDay::getSettingsNearKeyframe(const LLSettingsBase::TrackPosition &keyframe, S32 track, F32 fudge) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to get track (#" << track << ") out of range!" << LL_ENDL;
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
if (mDayTracks[track].empty())
{
LL_INFOS("DAYCYCLE") << "Empty track" << LL_ENDL;
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
TrackPosition startframe(keyframe - fudge);
if (startframe < 0.0f)
startframe = 1.0f + startframe;
CycleTrack_t::iterator it = get_wrapping_atafter(const_cast<CycleTrack_t &>(mDayTracks[track]), startframe);
F32 dist = get_wrapping_distance(startframe, (*it).first);
if (dist <= (fudge * 2.0f))
return (*it);
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
LLSettingsBase::TrackPosition LLSettingsDay::getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe)
{
return get_wrapping_atafter(mDayTracks[track], keyframe)->first;
}
LLSettingsBase::TrackPosition LLSettingsDay::getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe)
{
return get_wrapping_atbefore(mDayTracks[track], keyframe)->first;
}
LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe)
{
return TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe));
}
LLUUID LLSettingsDay::GetDefaultAssetId()
{
return DEFAULT_ASSET_ID;
}
//=========================================================================

View File

@@ -0,0 +1,156 @@
/**
* @file llsettingsdaycycle.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_SETTINGS_DAYCYCLE_H
#define LL_SETTINGS_DAYCYCLE_H
#include "llsettingsbase.h"
class LLSettingsWater;
class LLSettingsSky;
// These are alias for LLSettingsWater::ptr_t and LLSettingsSky::ptr_t respectively.
// Here for definitions only.
typedef PTR_NAMESPACE::shared_ptr<LLSettingsWater> LLSettingsWaterPtr_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> LLSettingsSkyPtr_t;
class LLSettingsDay : public LLSettingsBase
{
public:
// 32-bit as LLSD only supports that width at present
typedef S32Seconds Seconds;
static const std::string SETTING_KEYID;
static const std::string SETTING_KEYNAME;
static const std::string SETTING_KEYKFRAME;
static const std::string SETTING_KEYHASH;
static const std::string SETTING_TRACKS;
static const std::string SETTING_FRAMES;
static const Seconds MINIMUM_DAYLENGTH;
static const Seconds DEFAULT_DAYLENGTH;
static const Seconds MAXIMUM_DAYLENGTH;
static const Seconds MINIMUM_DAYOFFSET;
static const Seconds DEFAULT_DAYOFFSET;
static const Seconds MAXIMUM_DAYOFFSET;
static const S32 TRACK_WATER;
static const S32 TRACK_GROUND_LEVEL;
static const S32 TRACK_MAX;
static const S32 FRAME_MAX;
static const F32 DEFAULT_FRAME_SLOP_FACTOR;
static const LLUUID DEFAULT_ASSET_ID;
typedef std::map<LLSettingsBase::TrackPosition, LLSettingsBase::ptr_t> CycleTrack_t;
typedef std::vector<CycleTrack_t> CycleList_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsDay> ptr_t;
typedef PTR_NAMESPACE::weak_ptr<LLSettingsDay> wptr_t;
typedef std::vector<LLSettingsBase::TrackPosition> KeyframeList_t;
typedef std::pair<CycleTrack_t::iterator, CycleTrack_t::iterator> TrackBound_t;
//---------------------------------------------------------------------
LLSettingsDay(const LLSD &data);
virtual ~LLSettingsDay() { };
bool initialize(bool validate_frames = false);
virtual ptr_t buildClone() const = 0;
virtual ptr_t buildDeepCloneAndUncompress() const = 0;
virtual LLSD getSettings() const SETTINGS_OVERRIDE;
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_DAYCYCLE; }
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("daycycle"); }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &other, F64 mix) SETTINGS_OVERRIDE;
static LLSD defaults();
//---------------------------------------------------------------------
KeyframeList_t getTrackKeyframes(S32 track);
bool moveTrackKeyframe(S32 track, const LLSettingsBase::TrackPosition& old_frame, const LLSettingsBase::TrackPosition& new_frame);
bool removeTrackKeyframe(S32 track, const LLSettingsBase::TrackPosition& frame);
void setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, const LLSettingsBase::TrackPosition& keyframe);
LLSettingsWaterPtr_t getWaterAtKeyframe(const LLSettingsBase::TrackPosition& keyframe) const;
void setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, const LLSettingsBase::TrackPosition& keyframe, S32 track);
LLSettingsSkyPtr_t getSkyAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const;
void setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, const LLSettingsBase::TrackPosition& keyframe, S32 track);
LLSettingsBase::ptr_t getSettingsAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const;
CycleTrack_t::value_type getSettingsNearKeyframe(const LLSettingsBase::TrackPosition &keyframe, S32 track, F32 fudge) const;
//---------------------------------------------------------------------
void startDayCycle();
virtual LLSettingsSkyPtr_t getDefaultSky() const = 0;
virtual LLSettingsWaterPtr_t getDefaultWater() const = 0;
virtual LLSettingsSkyPtr_t buildSky(LLSD) const = 0;
virtual LLSettingsWaterPtr_t buildWater(LLSD) const = 0;
void setInitialized(bool value = true) { mInitialized = value; }
CycleTrack_t & getCycleTrack(S32 track);
const CycleTrack_t & getCycleTrackConst(S32 track) const;
bool clearCycleTrack(S32 track);
bool replaceCycleTrack(S32 track, const CycleTrack_t &source);
bool isTrackEmpty(S32 track) const;
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
LLSettingsBase::TrackPosition getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe);
LLSettingsBase::TrackPosition getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe);
static LLUUID GetDefaultAssetId();
protected:
LLSettingsDay();
virtual void updateSettings() SETTINGS_OVERRIDE;
bool mInitialized;
private:
CycleList_t mDayTracks;
LLSettingsBase::Seconds mLastUpdateTime;
void parseFromLLSD(LLSD &data);
static CycleTrack_t::iterator getEntryAtOrBefore(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
static CycleTrack_t::iterator getEntryAtOrAfter(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
TrackBound_t getBoundingEntries(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,361 @@
/**
* @file llsettingssky.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_SETTINGS_SKY_H
#define LL_SETTINGS_SKY_H
#include "llsettingsbase.h"
#include "v4coloru.h"
const F32 EARTH_RADIUS = 6.370e6f;
const F32 SUN_RADIUS = 695.508e6f;
const F32 SUN_DIST = 149598.260e6f;
const F32 MOON_RADIUS = 1.737e6f;
const F32 MOON_DIST = 384.400e6f;
class LLSettingsSky: public LLSettingsBase
{
public:
static const std::string SETTING_AMBIENT;
static const std::string SETTING_BLOOM_TEXTUREID;
static const std::string SETTING_RAINBOW_TEXTUREID;
static const std::string SETTING_HALO_TEXTUREID;
static const std::string SETTING_BLUE_DENSITY;
static const std::string SETTING_BLUE_HORIZON;
static const std::string SETTING_DENSITY_MULTIPLIER;
static const std::string SETTING_DISTANCE_MULTIPLIER;
static const std::string SETTING_HAZE_DENSITY;
static const std::string SETTING_HAZE_HORIZON;
static const std::string SETTING_CLOUD_COLOR;
static const std::string SETTING_CLOUD_POS_DENSITY1;
static const std::string SETTING_CLOUD_POS_DENSITY2;
static const std::string SETTING_CLOUD_SCALE;
static const std::string SETTING_CLOUD_SCROLL_RATE;
static const std::string SETTING_CLOUD_SHADOW;
static const std::string SETTING_CLOUD_TEXTUREID;
static const std::string SETTING_CLOUD_VARIANCE;
static const std::string SETTING_DOME_OFFSET;
static const std::string SETTING_DOME_RADIUS;
static const std::string SETTING_GAMMA;
static const std::string SETTING_GLOW;
static const std::string SETTING_LIGHT_NORMAL;
static const std::string SETTING_MAX_Y;
static const std::string SETTING_MOON_ROTATION;
static const std::string SETTING_MOON_SCALE;
static const std::string SETTING_MOON_TEXTUREID;
static const std::string SETTING_MOON_BRIGHTNESS;
static const std::string SETTING_STAR_BRIGHTNESS;
static const std::string SETTING_SUNLIGHT_COLOR;
static const std::string SETTING_SUN_ROTATION;
static const std::string SETTING_SUN_SCALE;
static const std::string SETTING_SUN_TEXTUREID;
static const std::string SETTING_PLANET_RADIUS;
static const std::string SETTING_SKY_BOTTOM_RADIUS;
static const std::string SETTING_SKY_TOP_RADIUS;
static const std::string SETTING_SUN_ARC_RADIANS;
static const std::string SETTING_MIE_ANISOTROPY_FACTOR;
static const std::string SETTING_RAYLEIGH_CONFIG;
static const std::string SETTING_MIE_CONFIG;
static const std::string SETTING_ABSORPTION_CONFIG;
static const std::string KEY_DENSITY_PROFILE;
static const std::string SETTING_DENSITY_PROFILE_WIDTH;
static const std::string SETTING_DENSITY_PROFILE_EXP_TERM;
static const std::string SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR;
static const std::string SETTING_DENSITY_PROFILE_LINEAR_TERM;
static const std::string SETTING_DENSITY_PROFILE_CONSTANT_TERM;
static const std::string SETTING_SKY_MOISTURE_LEVEL;
static const std::string SETTING_SKY_DROPLET_RADIUS;
static const std::string SETTING_SKY_ICE_LEVEL;
static const std::string SETTING_LEGACY_HAZE;
static const LLUUID DEFAULT_ASSET_ID;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> ptr_t;
//---------------------------------------------------------------------
LLSettingsSky(const LLSD &data);
virtual ~LLSettingsSky() { };
virtual ptr_t buildClone() const = 0;
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("sky"); }
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_SKY; }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
void replaceWithSky(LLSettingsSky::ptr_t pother);
static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f);
F32 getPlanetRadius() const;
F32 getSkyBottomRadius() const;
F32 getSkyTopRadius() const;
F32 getSunArcRadians() const;
F32 getMieAnisotropy() const;
F32 getSkyMoistureLevel() const;
F32 getSkyDropletRadius() const;
F32 getSkyIceLevel() const;
// Return first (only) profile layer represented in LLSD
LLSD getRayleighConfig() const;
LLSD getMieConfig() const;
LLSD getAbsorptionConfig() const;
// Return entire LLSDArray of profile layers represented in LLSD
LLSD getRayleighConfigs() const;
LLSD getMieConfigs() const;
LLSD getAbsorptionConfigs() const;
LLUUID getBloomTextureId() const;
LLUUID getRainbowTextureId() const;
LLUUID getHaloTextureId() const;
void setRayleighConfigs(const LLSD& rayleighConfig);
void setMieConfigs(const LLSD& mieConfig);
void setAbsorptionConfigs(const LLSD& absorptionConfig);
void setPlanetRadius(F32 radius);
void setSkyBottomRadius(F32 radius);
void setSkyTopRadius(F32 radius);
void setSunArcRadians(F32 radians);
void setMieAnisotropy(F32 aniso_factor);
void setSkyMoistureLevel(F32 moisture_level);
void setSkyDropletRadius(F32 radius);
void setSkyIceLevel(F32 ice_level);
//---------------------------------------------------------------------
LLColor3 getAmbientColor() const;
void setAmbientColor(const LLColor3 &val);
LLColor3 getCloudColor() const;
void setCloudColor(const LLColor3 &val);
LLUUID getCloudNoiseTextureId() const;
void setCloudNoiseTextureId(const LLUUID &id);
LLColor3 getCloudPosDensity1() const;
void setCloudPosDensity1(const LLColor3 &val);
LLColor3 getCloudPosDensity2() const;
void setCloudPosDensity2(const LLColor3 &val);
F32 getCloudScale() const;
void setCloudScale(F32 val);
LLVector2 getCloudScrollRate() const;
void setCloudScrollRate(const LLVector2 &val);
void setCloudScrollRateX(F32 val);
void setCloudScrollRateY(F32 val);
F32 getCloudShadow() const;
void setCloudShadow(F32 val);
F32 getCloudVariance() const;
void setCloudVariance(F32 val);
F32 getDomeOffset() const;
F32 getDomeRadius() const;
F32 getGamma() const;
void setGamma(F32 val);
LLColor3 getGlow() const;
void setGlow(const LLColor3 &val);
F32 getMaxY() const;
void setMaxY(F32 val);
LLQuaternion getMoonRotation() const;
void setMoonRotation(const LLQuaternion &val);
F32 getMoonScale() const;
void setMoonScale(F32 val);
LLUUID getMoonTextureId() const;
void setMoonTextureId(LLUUID id);
F32 getMoonBrightness() const;
void setMoonBrightness(F32 brightness_factor);
F32 getStarBrightness() const;
void setStarBrightness(F32 val);
LLColor3 getSunlightColor() const;
void setSunlightColor(const LLColor3 &val);
LLQuaternion getSunRotation() const;
void setSunRotation(const LLQuaternion &val) ;
F32 getSunScale() const;
void setSunScale(F32 val);
LLUUID getSunTextureId() const;
void setSunTextureId(LLUUID id);
//=====================================================================
// transient properties used in animations.
LLUUID getNextSunTextureId() const;
LLUUID getNextMoonTextureId() const;
LLUUID getNextCloudNoiseTextureId() const;
LLUUID getNextBloomTextureId() const;
//=====================================================================
virtual void loadTextures() { };
//=====================================================================
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
static LLSD translateLegacySettings(const LLSD& legacy);
// LEGACY_ATMOSPHERICS
static LLSD translateLegacyHazeSettings(const LLSD& legacy);
LLColor3 getLightAttenuation(F32 distance) const;
LLColor3 getLightTransmittance() const;
LLColor3 gammaCorrect(const LLColor3& in) const;
LLColor3 getBlueDensity() const;
LLColor3 getBlueHorizon() const;
F32 getHazeDensity() const;
F32 getHazeHorizon() const;
F32 getDensityMultiplier() const;
F32 getDistanceMultiplier() const;
void setBlueDensity(const LLColor3 &val);
void setBlueHorizon(const LLColor3 &val);
void setDensityMultiplier(F32 val);
void setDistanceMultiplier(F32 val);
void setHazeDensity(F32 val);
void setHazeHorizon(F32 val);
// Internal/calculated settings
bool getIsSunUp() const;
bool getIsMoonUp() const;
// determines how much the haze glow effect occurs in rendering
F32 getSunMoonGlowFactor() const;
LLVector3 getLightDirection() const;
LLColor3 getLightDiffuse() const;
LLVector3 getSunDirection() const;
LLVector3 getMoonDirection() const;
LLColor4 getMoonAmbient() const;
LLColor3 getMoonDiffuse() const;
LLColor4 getSunAmbient() const;
LLColor3 getSunDiffuse() const;
LLColor4 getTotalAmbient() const;
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
static LLUUID GetDefaultAssetId();
static LLUUID GetDefaultSunTextureId();
static LLUUID GetBlankSunTextureId();
static LLUUID GetDefaultMoonTextureId();
static LLUUID GetDefaultCloudNoiseTextureId();
static LLUUID GetDefaultBloomTextureId();
static LLUUID GetDefaultRainbowTextureId();
static LLUUID GetDefaultHaloTextureId();
static LLSD createDensityProfileLayer(
F32 width,
F32 exponential_term,
F32 exponential_scale_factor,
F32 linear_term,
F32 constant_term,
F32 aniso_factor = 0.0f);
static LLSD createSingleLayerDensityProfile(
F32 width,
F32 exponential_term,
F32 exponential_scale_factor,
F32 linear_term,
F32 constant_term,
F32 aniso_factor = 0.0f);
virtual void updateSettings() SETTINGS_OVERRIDE;
protected:
static const std::string SETTING_LEGACY_EAST_ANGLE;
static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL;
static const std::string SETTING_LEGACY_SUN_ANGLE;
LLSettingsSky();
virtual stringset_t getSlerpKeys() const SETTINGS_OVERRIDE;
virtual stringset_t getSkipInterpolateKeys() const SETTINGS_OVERRIDE;
LLUUID mNextSunTextureId;
LLUUID mNextMoonTextureId;
LLUUID mNextCloudTextureId;
LLUUID mNextBloomTextureId;
LLUUID mNextRainbowTextureId;
LLUUID mNextHaloTextureId;
private:
static LLSD rayleighConfigDefault();
static LLSD absorptionConfigDefault();
static LLSD mieConfigDefault();
void calculateHeavenlyBodyPositions() const;
void calculateLightSettings() const;
mutable LLVector3 mSunDirection;
mutable LLVector3 mMoonDirection;
mutable LLVector3 mLightDirection;
static const F32 DOME_RADIUS;
static const F32 DOME_OFFSET;
mutable LLColor4 mMoonAmbient;
mutable LLColor3 mMoonDiffuse;
mutable LLColor4 mSunAmbient;
mutable LLColor3 mSunDiffuse;
mutable LLColor4 mTotalAmbient;
typedef std::map<std::string, S32> mapNameToUniformId_t;
static mapNameToUniformId_t sNameToUniformMapping;
};
#endif

View File

@@ -0,0 +1,303 @@
/**
* @file llsettingswater.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llsettingswater.h"
#include <algorithm>
#include <boost/make_shared.hpp>
#include "llfasttimer.h"
#include "v3colorutil.h"
#include "imageids.h"
//=========================================================================
namespace
{
LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
}
//=========================================================================
const std::string LLSettingsWater::SETTING_BLUR_MULTIPLIER("blur_multiplier");
const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color");
const std::string LLSettingsWater::SETTING_FOG_DENSITY("water_fog_density");
const std::string LLSettingsWater::SETTING_FOG_MOD("underwater_fog_mod");
const std::string LLSettingsWater::SETTING_FRESNEL_OFFSET("fresnel_offset");
const std::string LLSettingsWater::SETTING_FRESNEL_SCALE("fresnel_scale");
const std::string LLSettingsWater::SETTING_TRANSPARENT_TEXTURE("transparent_texture");
const std::string LLSettingsWater::SETTING_NORMAL_MAP("normal_map");
const std::string LLSettingsWater::SETTING_NORMAL_SCALE("normal_scale");
const std::string LLSettingsWater::SETTING_SCALE_ABOVE("scale_above");
const std::string LLSettingsWater::SETTING_SCALE_BELOW("scale_below");
const std::string LLSettingsWater::SETTING_WAVE1_DIR("wave1_direction");
const std::string LLSettingsWater::SETTING_WAVE2_DIR("wave2_direction");
const std::string LLSettingsWater::SETTING_LEGACY_BLUR_MULTIPLIER("blurMultiplier");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_COLOR("waterFogColor");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_DENSITY("waterFogDensity");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_MOD("underWaterFogMod");
const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_OFFSET("fresnelOffset");
const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_SCALE("fresnelScale");
const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_MAP("normalMap");
const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_SCALE("normScale");
const std::string LLSettingsWater::SETTING_LEGACY_SCALE_ABOVE("scaleAbove");
const std::string LLSettingsWater::SETTING_LEGACY_SCALE_BELOW("scaleBelow");
const std::string LLSettingsWater::SETTING_LEGACY_WAVE1_DIR("wave1Dir");
const std::string LLSettingsWater::SETTING_LEGACY_WAVE2_DIR("wave2Dir");
const LLUUID LLSettingsWater::DEFAULT_ASSET_ID("59d1a851-47e7-0e5f-1ed7-6b715154f41a");
static const LLUUID DEFAULT_TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
static const LLUUID DEFAULT_OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
//=========================================================================
LLSettingsWater::LLSettingsWater(const LLSD &data) :
LLSettingsBase(data),
mNextNormalMapID()
{
}
LLSettingsWater::LLSettingsWater() :
LLSettingsBase(),
mNextNormalMapID()
{
}
//=========================================================================
LLSD LLSettingsWater::defaults(const LLSettingsBase::TrackPosition& position)
{
static LLSD dfltsetting;
if (dfltsetting.size() == 0)
{
// give the normal scale offset some variability over track time...
F32 normal_scale_offset = (position * 0.5f) - 0.25f;
// Magic constants copied form defaults.xml
dfltsetting[SETTING_BLUR_MULTIPLIER] = LLSD::Real(0.04000f);
dfltsetting[SETTING_FOG_COLOR] = LLColor3(0.0156f, 0.1490f, 0.2509f).getValue();
dfltsetting[SETTING_FOG_DENSITY] = LLSD::Real(2.0f);
dfltsetting[SETTING_FOG_MOD] = LLSD::Real(0.25f);
dfltsetting[SETTING_FRESNEL_OFFSET] = LLSD::Real(0.5f);
dfltsetting[SETTING_FRESNEL_SCALE] = LLSD::Real(0.3999);
dfltsetting[SETTING_TRANSPARENT_TEXTURE] = GetDefaultTransparentTextureAssetId();
dfltsetting[SETTING_NORMAL_MAP] = GetDefaultWaterNormalAssetId();
dfltsetting[SETTING_NORMAL_SCALE] = LLVector3(2.0f + normal_scale_offset, 2.0f + normal_scale_offset, 2.0f + normal_scale_offset).getValue();
dfltsetting[SETTING_SCALE_ABOVE] = LLSD::Real(0.0299f);
dfltsetting[SETTING_SCALE_BELOW] = LLSD::Real(0.2000f);
dfltsetting[SETTING_WAVE1_DIR] = LLVector2(1.04999f, -0.42000f).getValue();
dfltsetting[SETTING_WAVE2_DIR] = LLVector2(1.10999f, -1.16000f).getValue();
dfltsetting[SETTING_TYPE] = "water";
}
return dfltsetting;
}
LLSD LLSettingsWater::translateLegacySettings(LLSD legacy)
{
bool converted_something(false);
LLSD newsettings(defaults());
if (legacy.has(SETTING_LEGACY_BLUR_MULTIPLIER))
{
newsettings[SETTING_BLUR_MULTIPLIER] = LLSD::Real(legacy[SETTING_LEGACY_BLUR_MULTIPLIER].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_COLOR))
{
newsettings[SETTING_FOG_COLOR] = LLColor3(legacy[SETTING_LEGACY_FOG_COLOR]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_DENSITY))
{
newsettings[SETTING_FOG_DENSITY] = LLSD::Real(legacy[SETTING_LEGACY_FOG_DENSITY]);
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_MOD))
{
newsettings[SETTING_FOG_MOD] = LLSD::Real(legacy[SETTING_LEGACY_FOG_MOD].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FRESNEL_OFFSET))
{
newsettings[SETTING_FRESNEL_OFFSET] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_OFFSET].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FRESNEL_SCALE))
{
newsettings[SETTING_FRESNEL_SCALE] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_SCALE].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_NORMAL_MAP))
{
newsettings[SETTING_NORMAL_MAP] = LLSD::UUID(legacy[SETTING_LEGACY_NORMAL_MAP].asUUID());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_NORMAL_SCALE))
{
newsettings[SETTING_NORMAL_SCALE] = LLVector3(legacy[SETTING_LEGACY_NORMAL_SCALE]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_SCALE_ABOVE))
{
newsettings[SETTING_SCALE_ABOVE] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_ABOVE].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_SCALE_BELOW))
{
newsettings[SETTING_SCALE_BELOW] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_BELOW].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_WAVE1_DIR))
{
newsettings[SETTING_WAVE1_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE1_DIR]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_WAVE2_DIR))
{
newsettings[SETTING_WAVE2_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE2_DIR]).getValue();
converted_something |= true;
}
if (!converted_something)
return LLSD();
return newsettings;
}
void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
{
LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast<LLSettingsWater>(end);
if (other)
{
LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf);
replaceSettings(blenddata);
mNextNormalMapID = other->getNormalMapID();
mNextTransparentTextureID = other->getTransparentTextureID();
}
else
{
LL_WARNS("SETTINGS") << "Could not cast end settings to water. No blend performed." << LL_ENDL;
}
setBlendFactor(blendf);
}
void LLSettingsWater::replaceSettings(LLSD settings)
{
LLSettingsBase::replaceSettings(settings);
mNextNormalMapID.setNull();
mNextTransparentTextureID.setNull();
}
void LLSettingsWater::replaceWithWater(LLSettingsWater::ptr_t other)
{
replaceWith(other);
mNextNormalMapID = other->mNextNormalMapID;
mNextTransparentTextureID = other->mNextTransparentTextureID;
}
LLSettingsWater::validation_list_t LLSettingsWater::getValidationList() const
{
return LLSettingsWater::validationList();
}
LLSettingsWater::validation_list_t LLSettingsWater::validationList()
{
static validation_list_t validation;
if (validation.empty())
{ // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
// copy constructor for LLSDArray. Directly binding the LLSDArray as
// a parameter without first wrapping it in a pure LLSD object will result
// in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
validation.push_back(Validator(SETTING_BLUR_MULTIPLIER, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-0.5f)(0.5f)))));
validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f)))));
validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-10.0f)(10.0f)))));
validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(20.0f)))));
validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)),
LLSD(LLSDArray(10.0f)(10.0f)(10.0f)))));
validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
}
return validation;
}
LLUUID LLSettingsWater::GetDefaultAssetId()
{
return DEFAULT_ASSET_ID;
}
LLUUID LLSettingsWater::GetDefaultWaterNormalAssetId()
{
return DEFAULT_WATER_NORMAL;
}
LLUUID LLSettingsWater::GetDefaultTransparentTextureAssetId()
{
return DEFAULT_TRANSPARENT_WATER_TEXTURE;
}
LLUUID LLSettingsWater::GetDefaultOpaqueTextureAssetId()
{
return DEFAULT_OPAQUE_WATER_TEXTURE;
}
F32 LLSettingsWater::getModifiedWaterFogDensity(bool underwater) const
{
F32 fog_density = getWaterFogDensity();
F32 underwater_fog_mod = getFogMod();
if (underwater && underwater_fog_mod > 0.0f)
{
underwater_fog_mod = llclamp(underwater_fog_mod, 0.0f, 10.0f);
fog_density = pow(fog_density, underwater_fog_mod);
}
return fog_density;
}

View File

@@ -0,0 +1,249 @@
/**
* @file llsettingssky.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_SETTINGS_WATER_H
#define LL_SETTINGS_WATER_H
#include "llsettingsbase.h"
class LLSettingsWater : public LLSettingsBase
{
public:
static const std::string SETTING_BLUR_MULTIPLIER;
static const std::string SETTING_FOG_COLOR;
static const std::string SETTING_FOG_DENSITY;
static const std::string SETTING_FOG_MOD;
static const std::string SETTING_FRESNEL_OFFSET;
static const std::string SETTING_FRESNEL_SCALE;
static const std::string SETTING_TRANSPARENT_TEXTURE;
static const std::string SETTING_NORMAL_MAP;
static const std::string SETTING_NORMAL_SCALE;
static const std::string SETTING_SCALE_ABOVE;
static const std::string SETTING_SCALE_BELOW;
static const std::string SETTING_WAVE1_DIR;
static const std::string SETTING_WAVE2_DIR;
static const LLUUID DEFAULT_ASSET_ID;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsWater> ptr_t;
//---------------------------------------------------------------------
LLSettingsWater(const LLSD &data);
virtual ~LLSettingsWater() { };
virtual ptr_t buildClone() const = 0;
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("water"); }
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_WATER; }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
void replaceWithWater(LLSettingsWater::ptr_t other);
static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f);
//---------------------------------------------------------------------
F32 getBlurMultiplier() const
{
return mSettings[SETTING_BLUR_MULTIPLIER].asReal();
}
void setBlurMultiplier(F32 val)
{
setValue(SETTING_BLUR_MULTIPLIER, val);
}
LLColor3 getWaterFogColor() const
{
return LLColor3(mSettings[SETTING_FOG_COLOR]);
}
void setWaterFogColor(LLColor3 val)
{
setValue(SETTING_FOG_COLOR, val);
}
F32 getWaterFogDensity() const
{
return mSettings[SETTING_FOG_DENSITY].asReal();
}
F32 getModifiedWaterFogDensity(bool underwater) const;
void setWaterFogDensity(F32 val)
{
setValue(SETTING_FOG_DENSITY, val);
}
F32 getFogMod() const
{
return mSettings[SETTING_FOG_MOD].asReal();
}
void setFogMod(F32 val)
{
setValue(SETTING_FOG_MOD, val);
}
F32 getFresnelOffset() const
{
return mSettings[SETTING_FRESNEL_OFFSET].asReal();
}
void setFresnelOffset(F32 val)
{
setValue(SETTING_FRESNEL_OFFSET, val);
}
F32 getFresnelScale() const
{
return mSettings[SETTING_FRESNEL_SCALE].asReal();
}
void setFresnelScale(F32 val)
{
setValue(SETTING_FRESNEL_SCALE, val);
}
LLUUID getTransparentTextureID() const
{
return mSettings[SETTING_TRANSPARENT_TEXTURE].asUUID();
}
void setTransparentTextureID(LLUUID val)
{
setValue(SETTING_TRANSPARENT_TEXTURE, val);
}
LLUUID getNormalMapID() const
{
return mSettings[SETTING_NORMAL_MAP].asUUID();
}
void setNormalMapID(LLUUID val)
{
setValue(SETTING_NORMAL_MAP, val);
}
LLVector3 getNormalScale() const
{
return LLVector3(mSettings[SETTING_NORMAL_SCALE]);
}
void setNormalScale(LLVector3 val)
{
setValue(SETTING_NORMAL_SCALE, val);
}
F32 getScaleAbove() const
{
return mSettings[SETTING_SCALE_ABOVE].asReal();
}
void setScaleAbove(F32 val)
{
setValue(SETTING_SCALE_ABOVE, val);
}
F32 getScaleBelow() const
{
return mSettings[SETTING_SCALE_BELOW].asReal();
}
void setScaleBelow(F32 val)
{
setValue(SETTING_SCALE_BELOW, val);
}
LLVector2 getWave1Dir() const
{
return LLVector2(mSettings[SETTING_WAVE1_DIR]);
}
void setWave1Dir(LLVector2 val)
{
setValue(SETTING_WAVE1_DIR, val);
}
LLVector2 getWave2Dir() const
{
return LLVector2(mSettings[SETTING_WAVE2_DIR]);
}
void setWave2Dir(LLVector2 val)
{
setValue(SETTING_WAVE2_DIR, val);
}
//-------------------------------------------
LLUUID getNextNormalMapID() const
{
return mNextNormalMapID;
}
LLUUID getNextTransparentTextureID() const
{
return mNextTransparentTextureID;
}
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
static LLSD translateLegacySettings(LLSD legacy);
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
static LLUUID GetDefaultAssetId();
static LLUUID GetDefaultWaterNormalAssetId();
static LLUUID GetDefaultTransparentTextureAssetId();
static LLUUID GetDefaultOpaqueTextureAssetId();
protected:
static const std::string SETTING_LEGACY_BLUR_MULTIPLIER;
static const std::string SETTING_LEGACY_FOG_COLOR;
static const std::string SETTING_LEGACY_FOG_DENSITY;
static const std::string SETTING_LEGACY_FOG_MOD;
static const std::string SETTING_LEGACY_FRESNEL_OFFSET;
static const std::string SETTING_LEGACY_FRESNEL_SCALE;
static const std::string SETTING_LEGACY_NORMAL_MAP;
static const std::string SETTING_LEGACY_NORMAL_SCALE;
static const std::string SETTING_LEGACY_SCALE_ABOVE;
static const std::string SETTING_LEGACY_SCALE_BELOW;
static const std::string SETTING_LEGACY_WAVE1_DIR;
static const std::string SETTING_LEGACY_WAVE2_DIR;
LLSettingsWater();
LLUUID mNextTransparentTextureID;
LLUUID mNextNormalMapID;
};
#endif

View File

@@ -87,6 +87,7 @@ set(llmath_HEADER_FILES
raytrace.h
v2math.h
v3color.h
v3colorutil.h
v3dmath.h
v3math.h
v4color.h

View File

@@ -93,6 +93,11 @@ F32 LLCamera::getMaxView() const
: MAX_FIELD_OF_VIEW; // narrow views
}
LLPlane LLCamera::getUserClipPlane() const
{
return mAgentPlanes[AGENT_PLANE_USER_CLIP];
}
// ---------------- LLCamera::setFoo() member functions ----------------
void LLCamera::setUserClipPlane(const LLPlane& plane)

View File

@@ -154,6 +154,7 @@ public:
bool isChanged(); //check if mAgentPlanes changed since last frame.
LLPlane getUserClipPlane() const;
void setUserClipPlane(const LLPlane& plane);
void disableUserClipPlane();
virtual void setView(F32 vertical_fov_rads);

View File

@@ -104,6 +104,11 @@ LLQuaternion::LLQuaternion(const LLVector3 &x_axis,
normalize();
}
LLQuaternion::LLQuaternion(const LLSD &sd)
{
setValue(sd);
}
// Quatizations
void LLQuaternion::quantize16(F32 lower, F32 upper)
{
@@ -860,6 +865,26 @@ void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const
}
}
const LLQuaternion& LLQuaternion::setFromAzimuthAndAltitude(F32 azimuthRadians, F32 altitudeRadians)
{
// euler angle inputs are complements of azimuth/altitude which are measured from zenith
F32 pitch = llclamp(F_PI_BY_TWO - altitudeRadians, 0.0f, F_PI_BY_TWO);
F32 yaw = llclamp(F_PI_BY_TWO - azimuthRadians, 0.0f, F_PI_BY_TWO);
setEulerAngles(0.0f, pitch, yaw);
return *this;
}
void LLQuaternion::getAzimuthAndAltitude(F32 &azimuthRadians, F32 &altitudeRadians)
{
F32 rick_roll;
F32 pitch;
F32 yaw;
getEulerAngles(&rick_roll, &pitch, &yaw);
// make these measured from zenith
altitudeRadians = llclamp(F_PI_BY_TWO - pitch, 0.0f, F_PI_BY_TWO);
azimuthRadians = llclamp(F_PI_BY_TWO - yaw, 0.0f, F_PI_BY_TWO);
}
// quaternion does not need to be normalized
void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const
{

View File

@@ -28,6 +28,7 @@
#define LLQUATERNION_H
#include <iostream>
#include "llsd.h"
#ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies
#error "Please include llmath.h first."
@@ -63,6 +64,10 @@ public:
LLQuaternion(const LLVector3 &x_axis,
const LLVector3 &y_axis,
const LLVector3 &z_axis); // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis]
explicit LLQuaternion(const LLSD &sd); // Initializes Quaternion from LLSD array.
LLSD getValue() const;
void setValue(const LLSD& sd);
BOOL isIdentity() const;
BOOL isNotIdentity() const;
@@ -79,6 +84,7 @@ public:
const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW])
const LLQuaternion& set(const LLMatrix3 &mat); // Sets Quaternion to mat2quat(mat)
const LLQuaternion& set(const LLMatrix4 &mat); // Sets Quaternion to mat2quat(mat)
const LLQuaternion& setFromAzimuthAndAltitude(F32 azimuth, F32 altitude);
const LLQuaternion& setAngleAxis(F32 angle, F32 x, F32 y, F32 z); // Sets Quaternion to axis_angle2quat(angle, x, y, z)
const LLQuaternion& setAngleAxis(F32 angle, const LLVector3 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
@@ -100,6 +106,7 @@ public:
void getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const; // returns rotation in radians about axis x,y,z
void getAngleAxis(F32* angle, LLVector3 &vec) const;
void getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const;
void getAzimuthAndAltitude(F32 &azimuth, F32 &altitude);
F32 normalize(); // Normalizes Quaternion and returns magnitude
F32 normQuat(); // deprecated
@@ -166,6 +173,24 @@ public:
//static U32 mMultCount;
};
inline LLSD LLQuaternion::getValue() const
{
LLSD ret;
ret[0] = mQ[0];
ret[1] = mQ[1];
ret[2] = mQ[2];
ret[3] = mQ[3];
return ret;
}
inline void LLQuaternion::setValue(const LLSD& sd)
{
mQ[0] = sd[0].asReal();
mQ[1] = sd[1].asReal();
mQ[2] = sd[2].asReal();
mQ[3] = sd[3].asReal();
}
// checker
inline BOOL LLQuaternion::isFinite() const
{

View File

@@ -2195,6 +2195,12 @@ BOOL LLVolume::generate()
LLVector4a* end_profile = profile+sizeT;
LLVector4a offset = mPathp->mPath[s].mPos;
if (!offset.isFinite3())
{ // MAINT-5660; don't know why this happens, does not affect Release builds
LL_WARNS() << "LLVolume using path with non-finite points. Resetting them to 0,0,0" << LL_ENDL;
offset.clear();
}
LLVector4a tmp;
// Run along the profile.
@@ -2202,7 +2208,6 @@ BOOL LLVolume::generate()
{
rot_mat.rotate(*profile++, tmp);
dst->setAdd(tmp,offset);
llassert(dst->isFinite3());
++dst;
}
}

View File

@@ -118,7 +118,7 @@ LLSD LLVector2::getValue() const
return ret;
}
void LLVector2::setValue(LLSD& sd)
void LLVector2::setValue(const LLSD& sd)
{
mV[0] = (F32) sd[0].asReal();
mV[1] = (F32) sd[1].asReal();

View File

@@ -49,6 +49,7 @@ class LLVector2
LLVector2(F32 x, F32 y); // Initializes LLVector2 to (x. y)
LLVector2(const F32 *vec); // Initializes LLVector2 to (vec[0]. vec[1])
explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1])
explicit LLVector2(const LLSD &sd);
// Clears LLVector2 to (0, 0). DEPRECATED - prefer zeroVec.
void clear();
@@ -61,7 +62,7 @@ class LLVector2
void set(const F32 *vec); // Sets LLVector2 to vec
LLSD getValue() const;
void setValue(LLSD& sd);
void setValue(const LLSD& sd);
void setVec(F32 x, F32 y); // deprecated
void setVec(const LLVector2 &vec); // deprecated
@@ -145,6 +146,10 @@ inline LLVector2::LLVector2(const LLVector3 &vec)
mV[VY] = vec.mV[VY];
}
inline LLVector2::LLVector2(const LLSD &sd)
{
setValue(sd);
}
// Clear and Assignment Functions

View File

@@ -100,6 +100,23 @@ public:
const LLColor3& operator=(const LLColor4 &a);
LL_FORCE_INLINE LLColor3 divide(const LLColor3 &col2)
{
return LLColor3(
mV[0] / col2.mV[0],
mV[1] / col2.mV[1],
mV[2] / col2.mV[2] );
}
LL_FORCE_INLINE LLColor3 color_norm() const
{
F32 l = length();
return LLColor3(
mV[0] / l,
mV[1] / l,
mV[2] / l );
}
friend std::ostream& operator<<(std::ostream& s, const LLColor3 &a); // Print a
friend LLColor3 operator+(const LLColor3 &a, const LLColor3 &b); // Return vector a + b
friend LLColor3 operator-(const LLColor3 &a, const LLColor3 &b); // Return vector a minus b

115
indra/llmath/v3colorutil.h Normal file
View File

@@ -0,0 +1,115 @@
/**
* @file v3color.h
* @brief LLColor3 class header file.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_V3COLORUTIL_H
#define LL_V3COLORUTIL_H
#include "v3color.h"
inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
{
return LLColor3(left.mV[0] / right.mV[0],
left.mV[1] / right.mV[1],
left.mV[2] / right.mV[2]);
}
inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
{
return LLColor3(left.mV[0] * right.mV[0],
left.mV[1] * right.mV[1],
left.mV[2] * right.mV[2]);
}
inline LLColor3 componentExp(LLColor3 const &v)
{
return LLColor3(exp(v.mV[0]),
exp(v.mV[1]),
exp(v.mV[2]));
}
inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
{
return LLColor3(pow(v.mV[0], exponent),
pow(v.mV[1], exponent),
pow(v.mV[2], exponent));
}
inline LLColor3 componentSaturate(LLColor3 const &v)
{
return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
std::max(std::min(v.mV[1], 1.f), 0.f),
std::max(std::min(v.mV[2], 1.f), 0.f));
}
inline LLColor3 componentSqrt(LLColor3 const &v)
{
return LLColor3(sqrt(v.mV[0]),
sqrt(v.mV[1]),
sqrt(v.mV[2]));
}
inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
{
left.mV[0] *= right.mV[0];
left.mV[1] *= right.mV[1];
left.mV[2] *= right.mV[2];
}
inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
{
return (left + ((right - left) * amount));
}
inline LLColor3 smear(F32 val)
{
return LLColor3(val, val, val);
}
inline F32 color_intens(const LLColor3 &col)
{
return col.mV[0] + col.mV[1] + col.mV[2];
}
inline F32 color_max(const LLColor3 &col)
{
return llmax(col.mV[0], col.mV[1], col.mV[2]);
}
inline F32 color_max(const LLColor4 &col)
{
return llmax(col.mV[0], col.mV[1], col.mV[2]);
}
inline F32 color_min(const LLColor3 &col)
{
return llmin(col.mV[0], col.mV[1], col.mV[2]);
}
#endif

View File

@@ -114,9 +114,11 @@ class LLColor4
friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b
friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return component wise a * b
friend LLColor4 operator*(const LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change)
friend LLColor4 operator/(const LLColor4 &a, F32 k); // Return rgb divided by scalar k (no alpha change)
friend LLColor4 operator*(F32 k, const LLColor4 &a); // Return rgb times scaler k (no alpha change)
friend LLColor4 operator%(const LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change)
friend LLColor4 operator%(F32 k, const LLColor4 &a); // Return alpha times scaler k (no rgb change)
friend bool operator==(const LLColor4 &a, const LLColor4 &b); // Return a == b
friend bool operator!=(const LLColor4 &a, const LLColor4 &b); // Return a != b
@@ -477,6 +479,15 @@ inline LLColor4 operator*(const LLColor4 &a, F32 k)
a.mV[VW]);
}
inline LLColor4 operator/(const LLColor4 &a, F32 k)
{
return LLColor4(
a.mV[VX] / k,
a.mV[VY] / k,
a.mV[VZ] / k,
a.mV[VW]);
}
inline LLColor4 operator*(F32 k, const LLColor4 &a)
{
// only affects rgb (not a!)

View File

@@ -30,6 +30,7 @@
#include "llerror.h"
#include "llmath.h"
#include "v3math.h"
#include "v2math.h"
class LLMatrix3;
class LLMatrix4;
@@ -46,8 +47,11 @@ class LLVector4
LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1)
explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3])
explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);
explicit LLVector4(const LLVector2 &vec);
explicit LLVector4(const LLVector2 &vec, F32 z, F32 w);
explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1)
explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w)
explicit LLVector4(const LLSD &sd);
LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1)
LLVector4(F32 x, F32 y, F32 z, F32 w);
@@ -61,6 +65,15 @@ class LLVector4
return ret;
}
void setValue(const LLSD& sd)
{
mV[0] = sd[0].asReal();
mV[1] = sd[1].asReal();
mV[2] = sd[2].asReal();
mV[3] = sd[3].asReal();
}
inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
inline void clear(); // Clears LLVector4 to (0, 0, 0, 1)
@@ -175,6 +188,22 @@ inline LLVector4::LLVector4(const F64 *vec)
mV[VW] = (F32) vec[VW];
}
inline LLVector4::LLVector4(const LLVector2 &vec)
{
mV[VX] = vec[VX];
mV[VY] = vec[VY];
mV[VZ] = 0.f;
mV[VW] = 0.f;
}
inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w)
{
mV[VX] = vec[VX];
mV[VY] = vec[VY];
mV[VZ] = z;
mV[VW] = w;
}
inline LLVector4::LLVector4(const LLVector3 &vec)
{
mV[VX] = vec.mV[VX];
@@ -191,6 +220,11 @@ inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
mV[VW] = w;
}
inline LLVector4::LLVector4(const LLSD &sd)
{
setValue(sd);
}
inline BOOL LLVector4::isFinite() const
{

View File

@@ -58,6 +58,42 @@ const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-0
const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000); // microseconds
namespace
{
bool operator == (const LLAssetStorage::LLGetAssetCallback &lhs, const LLAssetStorage::LLGetAssetCallback &rhs)
{
auto fnPtrLhs = lhs.target<LLAssetStorage::LLGetAssetCallback>();
auto fnPtrRhs = rhs.target<LLAssetStorage::LLGetAssetCallback>();
if (fnPtrLhs && fnPtrRhs)
return (*fnPtrLhs == *fnPtrRhs);
else if (!fnPtrLhs && !fnPtrRhs)
return true;
return false;
}
// Rider: This is the general case of the operator declared above. The code compares the callback
// passed into the LLAssetStorage functions to determine if there are duplicated requests for an
// asset. Unfortunately std::function does not provide a direct way to compare two variables so
// we define the operator here.
// XCode is not very happy with the variadic temples in use below so we will just define the specific
// case of comparing two LLGetAssetCallback objects since that is all we really use.
//
// template<typename T, typename... U>
// bool operator == (const std::function<T(U...)> &a, const std::function <T(U...)> &b)
// {
// typedef T(fnType)(U...);
//
// auto fnPtrA = a.target<T(*)(U...)>();
// auto fnPtrB = b.target<T(*)(U...)>();
// if (fnPtrA && fnPtrB)
// return (*fnPtrA == *fnPtrB);
// else if (!fnPtrA && !fnPtrB)
// return true;
// return false;
// }
}
///----------------------------------------------------------------------------
/// LLAssetInfo
///----------------------------------------------------------------------------
@@ -150,13 +186,13 @@ void LLAssetInfo::setFromNameValue( const LLNameValue& nv )
}
///----------------------------------------------------------------------------
/// LLAssetRequest
/// LLBaseDownloadRequest
///----------------------------------------------------------------------------
LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType type)
: mUUID(uuid),
mType(type),
mDownCallback(NULL),
mDownCallback(),
mUserData(NULL),
mHost(),
mIsTemp(FALSE),
@@ -173,19 +209,21 @@ LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetTy
LLBaseDownloadRequest::~LLBaseDownloadRequest()
{
}
// virtual
LLBaseDownloadRequest* LLBaseDownloadRequest::getCopy()
{
return new LLBaseDownloadRequest(*this);
}
///----------------------------------------------------------------------------
/// LLAssetRequest
///----------------------------------------------------------------------------
LLAssetRequest::LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType type)
: LLBaseDownloadRequest(uuid, type),
mUpCallback( NULL ),
mUpCallback(),
mInfoCallback( NULL ),
mIsLocal(FALSE),
mIsUserWaiting(FALSE),
@@ -273,6 +311,7 @@ LLBaseDownloadRequest* LLEstateAssetRequest::getCopy()
return new LLEstateAssetRequest(*this);
}
///----------------------------------------------------------------------------
/// LLAssetStorage
///----------------------------------------------------------------------------
@@ -291,14 +330,12 @@ LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, LLVFS
_init(msg, xfer, vfs, static_vfs, upstream_host);
}
LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
LLVFS *vfs, LLVFS *static_vfs)
{
_init(msg, xfer, vfs, static_vfs, LLHost::invalid);
}
void LLAssetStorage::_init(LLMessageSystem *msg,
LLXferManager *xfer,
LLVFS *vfs,
@@ -443,7 +480,7 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse
// IW - uuid is passed by value to avoid side effects, please don't re-add &
void LLAssetStorage::getAssetData(const LLUUID uuid,
LLAssetType::EType type,
LLGetAssetCallback callback,
LLAssetStorage::LLGetAssetCallback callback,
void *user_data,
BOOL is_priority)
{
@@ -1305,9 +1342,13 @@ BOOL is_priority)
iter != mPendingDownloads.end(); )
{
LLAssetRequest* tmp = *iter++;
//void(*const* cbptr)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)
auto cbptr = tmp->mDownCallback.target<void(*)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)>();
if (type == tmp->getType() &&
uuid == tmp->getUUID() &&
legacyGetDataCallback == tmp->mDownCallback &&
(cbptr && (*cbptr == legacyGetDataCallback)) &&
callback == ((LLLegacyAssetRequest *)tmp->mUserData)->mDownCallback &&
user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData)
{

View File

@@ -29,6 +29,7 @@
#define LL_LLASSETSTORAGE_H
#include <string>
#include <functional>
#include "lluuid.h"
#include "lltimer.h"
@@ -60,6 +61,14 @@ const int LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE = -4;
const int LL_ERR_INSUFFICIENT_PERMISSIONS = -5;
const int LL_ERR_PRICE_MISMATCH = -23018;
// *TODO: these typedefs are passed into the VFS via a legacy C function pointer
// future project would be to convert these to C++ callables (std::function<>) so that
// we can use bind and remove the userData parameter.
//
typedef std::function<void(LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status)> LLGetAssetCallback;
typedef std::function<void(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)> LLStoreAssetCallback;
class LLAssetInfo
{
protected:
@@ -111,15 +120,13 @@ protected:
LLAssetType::EType mType;
public:
void (*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat);
LLGetAssetCallback mDownCallback;
// void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat);
void *mUserData;
LLHost mHost;
BOOL mIsTemp;
F64Seconds mTime; // Message system time
BOOL mIsPriority;
BOOL mDataSentInFirstPacket;
BOOL mDataIsInVFS;
@@ -135,7 +142,8 @@ public:
virtual LLBaseDownloadRequest* getCopy();
void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat);
LLStoreAssetCallback mUpCallback;
// void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat);
void (*mInfoCallback)(LLAssetInfo *, void *, S32);
BOOL mIsLocal;
@@ -185,8 +193,6 @@ protected:
// Map of known bad assets
typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id,
LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status);
class LLAssetStorage
@@ -195,7 +201,8 @@ public:
// VFS member is public because static child methods need it :(
LLVFS *mVFS;
LLVFS *mStaticVFS;
typedef void (*LLStoreAssetCallback)(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status);
typedef ::LLStoreAssetCallback LLStoreAssetCallback;
typedef ::LLGetAssetCallback LLGetAssetCallback;
enum ERequestType
{
@@ -240,10 +247,9 @@ public:
// public interface methods
// note that your callback may get called BEFORE the function returns
void getAssetData(const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback cb, void *user_data, BOOL is_priority = FALSE);
std::vector<LLUUID> mBlackListedAsset;
uuid_vec_t mBlackListedAsset;
/*
* TransactionID version
@@ -382,8 +388,8 @@ protected:
void _cleanupRequests(BOOL all, S32 error);
void _callUploadCallbacks(const LLUUID &uuid, const LLAssetType::EType asset_type, BOOL success, LLExtStat ext_status);
virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type,
void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback,
// void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
void *user_data, BOOL duplicate,
BOOL is_priority) = 0;
@@ -429,7 +435,7 @@ class LLLegacyAssetRequest
{
public:
void (*mDownCallback)(const char *, const LLUUID&, void *, S32, LLExtStat);
LLAssetStorage::LLStoreAssetCallback mUpCallback;
LLStoreAssetCallback mUpCallback;
void *mUserData;
};

View File

@@ -64,7 +64,7 @@ namespace LLAvatarNameCache
std::string sNameLookupURL;
// Accumulated agent IDs for next query against service
typedef std::set<LLUUID> ask_queue_t;
typedef uuid_set_t ask_queue_t;
ask_queue_t sAskQueue;
// Agent IDs that have been requested, but with no reply.
@@ -175,14 +175,14 @@ class LLAvatarNameResponder : public LLHTTPClient::ResponderWithResult
private:
// need to store agent ids that are part of this request in case of
// an error, so we can flag them as unavailable
std::vector<LLUUID> mAgentIDs;
uuid_vec_t mAgentIDs;
// Need the headers to look up Expires: and Retry-After:
/*virtual*/ bool needsHeaders() const { return true; }
/*virtual*/ char const* getName() const { return "LLAvatarNameResponder"; }
public:
LLAvatarNameResponder(const std::vector<LLUUID>& agent_ids)
LLAvatarNameResponder(const uuid_vec_t& agent_ids)
: mAgentIDs(agent_ids)
{ }
@@ -253,7 +253,7 @@ protected:
LL_WARNS("AvNameCache") << dumpResponse() << LL_ENDL;
// Add dummy records for any agent IDs in this request that we do not have cached already
std::vector<LLUUID>::const_iterator it = mAgentIDs.begin();
auto it = mAgentIDs.begin();
for ( ; it != mAgentIDs.end(); ++it)
{
const LLUUID& agent_id = *it;
@@ -327,7 +327,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
std::string url;
url.reserve(NAME_URL_MAX);
std::vector<LLUUID> agent_ids;
uuid_vec_t agent_ids;
agent_ids.reserve(128);
U32 ids = 0;

View File

@@ -185,7 +185,7 @@ void ReplySender::flush()
}
typedef std::set<LLUUID> AskQueue;
typedef uuid_set_t AskQueue;
typedef std::list<PendingReply*> ReplyQueue;
typedef std::map<LLUUID,U32> PendingQueue;
typedef std::map<LLUUID, LLCacheNameEntry*> Cache;

View File

@@ -544,7 +544,7 @@ void LLCircuitData::checkPeriodTime()
mBytesOutLastPeriod = mBytesOutThisPeriod;
mBytesInThisPeriod = S32Bytes(0);
mBytesOutThisPeriod = S32Bytes(0);
mLastPeriodLength = period_length;
mLastPeriodLength = F32Seconds::convert(period_length);
mPeriodTime = mt_sec;
}
@@ -1390,8 +1390,8 @@ F32Milliseconds LLCircuitData::getPingInTransitTime()
if (mPingsInTransit)
{
time_since_ping_was_sent = ((mPingsInTransit*mHeartbeatInterval - F32Seconds(1))
+ (LLMessageSystem::getMessageTimeSeconds() - mPingTime));
time_since_ping_was_sent = F32Milliseconds::convert(((mPingsInTransit*mHeartbeatInterval - F32Seconds(1))
+ (LLMessageSystem::getMessageTimeSeconds() - mPingTime)));
}
return time_since_ping_was_sent;

View File

@@ -29,6 +29,7 @@
#include "lldispatcher.h"
#include <algorithm>
#include <iterator>
#include "llstl.h"
#include "message.h"
@@ -145,3 +146,25 @@ bool LLDispatcher::unpackMessage(
}
return true;
}
// static
bool LLDispatcher::unpackLargeMessage(
LLMessageSystem* msg,
LLDispatcher::key_t& method,
LLUUID& invoice,
LLDispatcher::sparam_t& parameters)
{
msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);
msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice);
S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
for (S32 i = 0; i < count; ++i)
{
// This method treats all Parameter List params as strings and unpacks
// them regardless of length. If there is binary data it is the callers
// responsibility to decode it.
std::string param;
msg->getStringFast(_PREHASH_ParamList, _PREHASH_Parameter, param, i);
parameters.push_back(param);
}
return true;
}

View File

@@ -105,6 +105,12 @@ public:
LLUUID& invoice,
sparam_t& parameters);
static bool unpackLargeMessage(
LLMessageSystem* msg,
key_t& method,
LLUUID& invoice,
sparam_t& parameters);
protected:
typedef std::map<key_t, LLDispatchHandler*> dispatch_map_t;
dispatch_map_t mHandlers;

View File

@@ -42,6 +42,9 @@ const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3);
// Does the sun move?
const U64 REGION_FLAGS_SUN_FIXED = (1 << 4);
// Does the estate owner allow private parcels?
const U64 REGION_FLAGS_ALLOW_ACCESS_OVERRIDE = (1 << 5);
// Can't change the terrain heightfield, even on owned parcels,
// but can plant trees and grass.
const U64 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6);
@@ -51,6 +54,9 @@ const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7);
// All content wiped once per night
const U64 REGION_FLAGS_SANDBOX = (1 << 8);
const U64 REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE = (1 << 9);
const U64 REGION_FLAGS_GAMING = (1 << 10); // Denotes a gaming region on certain grids
const U64 REGION_FLAGS_HIDE_FROM_SEARCH = (1 << 11); // Hides region from search on certain grids
const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies

View File

@@ -618,6 +618,7 @@ char const* const _PREHASH_GroupAccountSummaryRequest = LLMessageStringTable::ge
char const* const _PREHASH_GroupVoteHistoryRequest = LLMessageStringTable::getInstance()->getString("GroupVoteHistoryRequest");
char const* const _PREHASH_ParamValue = LLMessageStringTable::getInstance()->getString("ParamValue");
char const* const _PREHASH_MaxAgents = LLMessageStringTable::getInstance()->getString("MaxAgents");
char const* const _PREHASH_HardMaxAgents = LLMessageStringTable::getInstance()->getString("HardMaxAgents");
char const* const _PREHASH_CreateNewOutfitAttachments = LLMessageStringTable::getInstance()->getString("CreateNewOutfitAttachments");
char const* const _PREHASH_RegionHandle = LLMessageStringTable::getInstance()->getString("RegionHandle");
char const* const _PREHASH_TeleportProgress = LLMessageStringTable::getInstance()->getString("TeleportProgress");
@@ -1374,6 +1375,11 @@ char const* const _PREHASH_OwnerMask = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_TransferInventoryAck = LLMessageStringTable::getInstance()->getString("TransferInventoryAck");
char const* const _PREHASH_RegionDenyAgeUnverified = LLMessageStringTable::getInstance()->getString("RegionDenyAgeUnverified");
char const* const _PREHASH_AgeVerificationBlock = LLMessageStringTable::getInstance()->getString("AgeVerificationBlock");
char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getInstance()->getString("RegionAllowAccessBlock");
char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
char const* const _PREHASH_ParcelEnvironmentBlock = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentBlock");
char const* const _PREHASH_ParcelEnvironmentVersion = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentVersion");
char const* const _PREHASH_RegionAllowEnvironmentOverride = LLMessageStringTable::getInstance()->getString("RegionAllowEnvironmentOverride");
char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");
char const* const _PREHASH_FaceIndex = LLMessageStringTable::getInstance()->getString("FaceIndex");

View File

@@ -618,6 +618,7 @@ extern char const* const _PREHASH_GroupAccountSummaryRequest;
extern char const* const _PREHASH_GroupVoteHistoryRequest;
extern char const* const _PREHASH_ParamValue;
extern char const* const _PREHASH_MaxAgents;
extern char const* const _PREHASH_HardMaxAgents;
extern char const* const _PREHASH_CreateNewOutfitAttachments;
extern char const* const _PREHASH_RegionHandle;
extern char const* const _PREHASH_TeleportProgress;
@@ -1374,6 +1375,11 @@ extern char const* const _PREHASH_OwnerMask;
extern char const* const _PREHASH_TransferInventoryAck;
extern char const* const _PREHASH_RegionDenyAgeUnverified;
extern char const* const _PREHASH_AgeVerificationBlock;
extern char const* const _PREHASH_RegionAllowAccessBlock;
extern char const* const _PREHASH_RegionAllowAccessOverride;
extern char const* const _PREHASH_ParcelEnvironmentBlock;
extern char const* const _PREHASH_ParcelEnvironmentVersion;
extern char const* const _PREHASH_RegionAllowEnvironmentOverride;
extern char const* const _PREHASH_UCoord;
extern char const* const _PREHASH_VCoord;
extern char const* const _PREHASH_FaceIndex;

View File

@@ -62,6 +62,7 @@ bool LLPluginClassMedia::init_impl(void)
return true;
}
void LLPluginClassMedia::reset_impl(void)
{
mTextureParamsReceived = false;
@@ -91,16 +92,22 @@ void LLPluginClassMedia::reset_impl(void)
mMediaHeight = 0;
mDirtyRect = LLRect::null;
mAutoScaleMedia = false;
mRequestedVolume = 1.0f;
mRequestedVolume = 0.0f;
mPriority = PRIORITY_NORMAL;
mLowPrioritySizeLimit = LOW_PRIORITY_TEXTURE_SIZE_DEFAULT;
mAllowDownsample = false;
mPadding = 0;
mLastMouseX = 0;
mLastMouseY = 0;
mStatus = LLPluginClassMediaOwner::MEDIA_NONE;
mSleepTime = 1.0f / 100.0f;
mCanUndo = false;
mCanRedo = false;
mCanCut = false;
mCanCopy = false;
mCanPaste = false;
mCanDoDelete = false;
mCanSelectAll = false;
mMediaName.clear();
mMediaDescription.clear();
mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f);
@@ -119,6 +126,10 @@ void LLPluginClassMedia::reset_impl(void)
mClickUUID.clear();
mStatusCode = 0;
mClickEnforceTarget = false;
mZoomFactor = 1.0;
// media_time class
mCurrentTime = 0.0f;
mDuration = 0.0f;
@@ -128,7 +139,12 @@ void LLPluginClassMedia::reset_impl(void)
void LLPluginClassMedia::idle_impl(void)
{
if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()) || (mOwner == NULL))
if(mPlugin)
{
mPlugin->idle();
}
if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == nullptr) || (mPlugin->isBlocked()) || (mOwner == nullptr))
{
// Can't process a size change at this time
}
@@ -189,7 +205,14 @@ void LLPluginClassMedia::idle_impl(void)
void *addr = mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName);
// clear texture memory to avoid random screen visual fuzz from uninitialized texture data
memset( addr, 0x00, newsize );
if (addr)
{
memset( addr, 0x00, newsize );
}
else
{
LL_WARNS("Plugin") << "Failed to get previously created shared memory address: " << mTextureSharedMemoryName << " size: " << mTextureSharedMemorySize << LL_ENDL;
}
// We could do this to force an update, but textureValid() will still be returning false until the first roundtrip to the plugin,
// so it may not be worthwhile.
@@ -237,8 +260,8 @@ int LLPluginClassMedia::getTextureHeight() const
unsigned char* LLPluginClassMedia::getBitsData()
{
unsigned char *result = NULL;
if((mPlugin != NULL) && !mTextureSharedMemoryName.empty())
unsigned char *result = nullptr;
if((mPlugin != nullptr) && !mTextureSharedMemoryName.empty())
{
result = (unsigned char*)mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName);
}
@@ -335,7 +358,7 @@ bool LLPluginClassMedia::textureValid(void)
mMediaHeight <= 0 ||
mRequestedMediaWidth != mMediaWidth ||
mRequestedMediaHeight != mMediaHeight ||
getBitsData() == NULL
getBitsData() == nullptr
)
return false;
@@ -346,7 +369,7 @@ bool LLPluginClassMedia::getDirty(LLRect *dirty_rect)
{
bool result = !mDirtyRect.isEmpty();
if(dirty_rect != NULL)
if(dirty_rect != nullptr)
{
*dirty_rect = mDirtyRect;
}
@@ -678,15 +701,22 @@ F64 LLPluginClassMedia::getCPUUsage()
return result;
}
void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
void LLPluginClassMedia::sendPickFileResponse(const std::vector<std::string> files)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
message.setValue("file", file);
if(mPlugin && mPlugin->isBlocked())
{
// If the plugin sent a blocking pick-file request, the response should unblock it.
message.setValueBoolean("blocking_response", true);
}
LLSD file_list = LLSD::emptyArray();
for (std::vector<std::string>::const_iterator in_iter = files.begin(); in_iter != files.end(); ++in_iter)
{
file_list.append(LLSD::String(*in_iter));
}
message.setValueLLSD("file_list", file_list);
sendMessage(message);
}
@@ -704,6 +734,18 @@ void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username,
sendMessage(message);
}
void LLPluginClassMedia::undo()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_undo");
sendMessage(message);
}
void LLPluginClassMedia::redo()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_redo");
sendMessage(message);
}
void LLPluginClassMedia::cut()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut");
@@ -722,12 +764,33 @@ void LLPluginClassMedia::paste()
sendMessage(message);
}
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_logs)
void LLPluginClassMedia::doDelete()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_delete");
sendMessage(message);
}
void LLPluginClassMedia::selectAll()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_select_all");
sendMessage(message);
}
void LLPluginClassMedia::showPageSource()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_show_source");
sendMessage(message);
}
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
const std::string &user_data_path_cookies,
const std::string &user_data_path_cef_log)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
message.setValue("cache_path", user_data_path_cache);
message.setValue("cookies_path", user_data_path_cookies);
message.setValue("logs_path", user_data_path_logs);
message.setValue("cef_log_file", user_data_path_cef_log);
sendMessage(message);
}
@@ -825,7 +888,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mDirtyRect.unionWith(newDirtyRect);
}
LL_DEBUGS("PluginUpdated") << "adjusted incoming rect is: ("
LL_DEBUGS("PluginUpdated") << "adjusted incoming rect is: ("
<< newDirtyRect.mLeft << ", "
<< newDirtyRect.mTop << ", "
<< newDirtyRect.mRight << ", "
@@ -926,7 +989,6 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
S32 width = message.getValueS32("width");
S32 height = message.getValueS32("height");
std::string name = message.getValue("name");
// TODO: check that name matches?
mNaturalMediaWidth = width;
@@ -936,10 +998,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
}
else if(message_name == "size_change_response")
{
std::string name = message.getValue("name");
// TODO: check that name matches?
mTextureWidth = message.getValueS32("texture_width");
mTextureHeight = message.getValueS32("texture_height");
mMediaWidth = message.getValueS32("width");
@@ -961,6 +1020,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
}
else if(message_name == "edit_state")
{
if(message.hasValue("undo"))
{
mCanUndo = message.getValueBoolean("undo");
}
if(message.hasValue("redo"))
{
mCanRedo = message.getValueBoolean("redo");
}
if(message.hasValue("cut"))
{
mCanCut = message.getValueBoolean("cut");
@@ -973,14 +1040,25 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mCanPaste = message.getValueBoolean("paste");
}
if (message.hasValue("delete"))
{
mCanDoDelete = message.getValueBoolean("delete");
}
if (message.hasValue("select_all"))
{
mCanSelectAll = message.getValueBoolean("select_all");
}
}
else if(message_name == "name_text")
{
mHistoryBackAvailable = message.getValueBoolean("history_back_available");
mHistoryForwardAvailable = message.getValueBoolean("history_forward_available");
mMediaName = message.getValue("name");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED);
}
else if(message_name == "pick_file")
{
mIsMultipleFilePick = message.getValueBoolean("multiple_files");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
}
else if(message_name == "auth_request")
@@ -1042,7 +1120,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mClickURL = message.getValue("uri");
mClickTarget = message.getValue("target");
mClickUUID = message.getValue("uuid");
// need a link to have a UUID that identifies it to a system further
// upstream - plugin could make it but we have access to LLUUID here
// so why don't we use it
mClickUUID = LLUUID::generateNewID().asString();
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
}
else if(message_name == "click_nofollow")
@@ -1057,13 +1140,6 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mStatusCode = message.getValueS32("status_code");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE);
}
else if(message_name == "cookie_set")
{
if(mOwner)
{
mOwner->handleCookieSet(this, message.getValue("cookie"));
}
}
else if(message_name == "close_request")
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST);
@@ -1102,7 +1178,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
// }
// else
{
LL_WARNS("Plugin") << "Unknown " << message_class << " class message: " << message_name << LL_ENDL;
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
}
}
@@ -1145,7 +1221,7 @@ void LLPluginClassMedia::focus(bool focused)
sendMessage(message);
}
void LLPluginClassMedia::set_page_zoom_factor( double factor )
void LLPluginClassMedia::set_page_zoom_factor( F64 factor )
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_page_zoom_factor");
@@ -1165,27 +1241,23 @@ void LLPluginClassMedia::clear_cookies()
sendMessage(message);
}
void LLPluginClassMedia::set_cookies(const std::string &cookies)
void LLPluginClassMedia::cookies_enabled(bool enable)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
message.setValue("cookies", cookies);
sendMessage(message);
}
void LLPluginClassMedia::enable_cookies(bool enable)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies");
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookies_enabled");
message.setValueBoolean("enable", enable);
sendMessage(message);
}
void LLPluginClassMedia::proxy_setup(bool enable, const std::string &host, int port)
void LLPluginClassMedia::proxy_setup(bool enable, int type, const std::string &host, int port, const std::string &user, const std::string &pass)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_setup");
message.setValueBoolean("enable", enable);
message.setValueS32("proxy_type", type);
message.setValue("host", host);
message.setValueS32("port", port);
message.setValue("username", user);
message.setValue("password", pass);
sendMessage(message);
}
@@ -1217,16 +1289,6 @@ void LLPluginClassMedia::browse_back()
sendMessage(message);
}
void LLPluginClassMedia::set_status_redirect(int code, const std::string &url)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_status_redirect");
message.setValueS32("code", code);
message.setValue("url", url);
sendMessage(message);
}
void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_user_agent");
@@ -1276,6 +1338,12 @@ void LLPluginClassMedia::addCertificateFilePath(const std::string& path)
sendMessage(message);
}
void LLPluginClassMedia::setOverrideClickTarget(const std::string &target)
{
mClickEnforceTarget = true;
mOverrideClickTarget = target;
}
void LLPluginClassMedia::crashPlugin()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash");

View File

@@ -57,6 +57,7 @@ public:
int getTextureHeight() const;
int getFullWidth() const { return mFullMediaWidth; };
int getFullHeight() const { return mFullMediaHeight; };
F64 getZoomFactor() const { return mZoomFactor; };
// This may return NULL. Callers need to check for and handle this case.
unsigned char* getBitsData();
@@ -72,6 +73,7 @@ public:
void setSize(int width, int height);
void setAutoScale(bool auto_scale);
void setZoomFactor(F64 zoom_factor) { mZoomFactor = zoom_factor; }
void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
@@ -83,7 +85,7 @@ public:
// until you call idle() again.
bool textureValid(void);
bool getDirty(LLRect *dirty_rect = NULL);
bool getDirty(LLRect *dirty_rect = nullptr);
void resetDirty(void);
typedef enum
@@ -127,9 +129,9 @@ public:
void loadURI(const std::string &uri);
// Inherited from LLPluginProcessParentOwner
/* virtual */ void receivePluginMessage(const LLPluginMessage &message);
/* virtual */ void pluginLaunchFailed();
/* virtual */ void pluginDied();
/* virtual */ void receivePluginMessage(const LLPluginMessage &message) override;
/* virtual */ void pluginLaunchFailed() override;
/* virtual */ void pluginDied() override;
// Inherited from LLPluginClassBasic
/* virtual */ void priorityChanged(EPriority priority);
@@ -137,7 +139,7 @@ public:
F64 getCPUUsage();
void sendPickFileResponse(const std::string &file);
void sendPickFileResponse(const std::vector<std::string> files);
void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
@@ -146,6 +148,12 @@ public:
LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; }
void undo();
bool canUndo() const { return mCanUndo; };
void redo();
bool canRedo() const { return mCanRedo; };
void cut();
bool canCut() const { return mCanCut; };
@@ -155,8 +163,16 @@ public:
void paste();
bool canPaste() const { return mCanPaste; };
void doDelete();
bool canDoDelete() const { return mCanDoDelete; };
void selectAll();
bool canSelectAll() const { return mCanSelectAll; };
void showPageSource();
// These can be called before init(), and they will be queued and sent before the media init message.
void setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_logs);
void setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_cef_log);
void setLanguageCode(const std::string &language_code);
void setPluginsEnabled(const bool enabled);
void setJavascriptEnabled(const bool enabled);
@@ -167,17 +183,15 @@ public:
bool pluginSupportsMediaBrowser(void);
void focus(bool focused);
void set_page_zoom_factor( double factor );
void set_page_zoom_factor( F64 factor );
void clear_cache();
void clear_cookies();
void set_cookies(const std::string &cookies);
void enable_cookies(bool enable);
void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
void cookies_enabled(bool enable);
void proxy_setup(bool enable, int type = 0, const std::string &host = LLStringUtil::null, int port = 0, const std::string &user = LLStringUtil::null, const std::string &pass = LLStringUtil::null);
void browse_stop();
void browse_reload(bool ignore_cache = false);
void browse_forward();
void browse_back();
void set_status_redirect(int code, const std::string &url);
void setBrowserUserAgent(const std::string& user_agent);
void showWebInspector( bool show );
void proxyWindowOpened(const std::string &target, const std::string &uuid);
@@ -215,6 +229,13 @@ public:
// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
std::string getClickUUID() const { return mClickUUID; };
// mClickTarget is received from message and governs how link will be opened
// use this to enforce your own way of opening links inside plugins
void setOverrideClickTarget(const std::string &target);
void resetOverrideClickTarget() { mClickEnforceTarget = false; };
bool isOverrideClickTarget() const { return mClickEnforceTarget; }
std::string getOverrideClickTarget() const { return mOverrideClickTarget; };
// These are valid during MEDIA_EVENT_DEBUG_MESSAGE
std::string getDebugMessageText() const { return mDebugMessageText; };
std::string getDebugMessageLevel() const { return mDebugMessageLevel; };
@@ -232,6 +253,9 @@ public:
std::string getAuthURL() const { return mAuthURL; };
std::string getAuthRealm() const { return mAuthRealm; };
// These are valid during MEDIA_EVENT_PICK_FILE_REQUEST
bool getIsMultipleFilePick() const { return mIsMultipleFilePick; }
// These are valid during MEDIA_EVENT_LINK_HOVERED
std::string getHoverText() const { return mHoverText; };
std::string getHoverLink() const { return mHoverLink; };
@@ -326,8 +350,12 @@ protected:
int mMediaWidth;
int mMediaHeight;
F64 mZoomFactor;
float mRequestedVolume;
// Priority of this media stream
EPriority mPriority;
int mLowPrioritySizeLimit;
bool mAllowDownsample;
@@ -343,9 +371,15 @@ protected:
LLPluginClassMediaOwner::EMediaStatus mStatus;
F64 mSleepTime;
bool mCanUndo;
bool mCanRedo;
bool mCanCut;
bool mCanCopy;
bool mCanPaste;
bool mCanDoDelete;
bool mCanSelectAll;
std::string mMediaName;
std::string mMediaDescription;
@@ -368,6 +402,8 @@ protected:
std::string mClickNavType;
std::string mClickTarget;
std::string mClickUUID;
bool mClickEnforceTarget;
std::string mOverrideClickTarget;
std::string mDebugMessageText;
std::string mDebugMessageLevel;
S32 mGeometryX;
@@ -380,6 +416,7 @@ protected:
std::string mHoverText;
std::string mHoverLink;
std::string mFileDownloadFilename;
bool mIsMultipleFilePick;
/////////////////////////////////////////
// media_time class

View File

@@ -34,7 +34,6 @@
#include <queue>
class LLPluginClassMedia;
class LLPluginCookieStore;
class LLPluginClassMediaOwner
{
@@ -86,7 +85,6 @@ public:
virtual ~LLPluginClassMediaOwner() {};
virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {};
virtual void handleCookieSet(LLPluginClassMedia* /*self*/, const std::string &/*cookie*/) {};
};
#endif // LL_LLPLUGINCLASSMEDIAOWNER_H

View File

@@ -31,11 +31,8 @@
// Freetype stuff
#include <ft2build.h>
// For some reason, this won't work if it's not wrapped in the ifdef
#ifdef FT_FREETYPE_H
#include FT_FREETYPE_H
#endif
#include "llerror.h"
#include "llimage.h"
@@ -279,7 +276,7 @@ F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const
F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
{
if (mFTFace == NULL)
if (mFTFace == nullptr)
return 0.0;
//llassert(!mIsFallback);
@@ -298,7 +295,7 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const
{
if (mFTFace == NULL)
if (mFTFace == nullptr)
return 0.0;
U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
@@ -487,20 +484,12 @@ void LLFontFreetype::renderGlyph(const U32 glyph_index) const
if (mFTFace == NULL)
return;
FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT);
#ifdef SHOW_ASSERT
if (error)
if (FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_RENDER | FT_LOAD_TARGET_LIGHT) != 0)
{
LL_ERRS() << "FT_Load_Glyph returned " << error << LL_ENDL;
// If glyph fails to load and/or render, render a fallback character
llassert_always(!FT_Load_Char(mFTFace, L'?', FT_LOAD_RENDER | FT_LOAD_TARGET_LIGHT));
}
#endif
error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
#ifdef SHOW_ASSERT
if (error)
{
LL_ERRS() << "FT_Render_Glyph returned " << error << LL_ENDL;
}
#endif
mRenderGlyphCount++;
}
@@ -568,6 +557,7 @@ U8 LLFontFreetype::getStyle() const
{
return mStyle;
}
void LLFontFreetype::setSubImageLuminanceAlpha(const U32 x, const U32 y, const U32 bitmap_num, const U32 width, const U32 height, const U8 *data, S32 stride) const
{
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);

View File

@@ -26,24 +26,28 @@
#include "linden_common.h"
#include "llfontgl.h"
// Linden library includes
#include "llfasttimer.h"
#include "llfontfreetype.h"
#include "llfontbitmapcache.h"
#include "llfontregistry.h"
#include "llgl.h"
#include "llrender.h"
#include "lltexture.h"
#include "v4color.h"
#include "llstl.h"
#include "llfasttimer.h"
#include "v4color.h"
#include "lltexture.h"
#include "lldir.h"
// Third party library includes
#include <boost/tokenizer.hpp>
#if LL_WINDOWS
#include "llwin32headerslean.h"
#include <shlobj.h>
#endif
const S32 BOLD_OFFSET = 1;
// static class members
@@ -52,7 +56,7 @@ F32 LLFontGL::sHorizDPI = 96.f;
F32 LLFontGL::sScaleX = 1.f;
F32 LLFontGL::sScaleY = 1.f;
BOOL LLFontGL::sDisplayFont = TRUE ;
std::string LLFontGL::sAppDir;
std::string LLFontGL::sFontDir;
LLColor4U LLFontGL::sShadowColor(0, 0, 0, 255);
LLFontRegistry* LLFontGL::sFontRegistry = NULL;
@@ -937,7 +941,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
sScaleX = x_scale;
sScaleY = y_scale;
sAppDir = app_dir;
sFontDir = app_dir;
// Font registry init
if (!sFontRegistry)
@@ -997,7 +1001,7 @@ void LLFontGL::destroyAllGL()
// static
U8 LLFontGL::getStyleFromString(const std::string &style)
{
S32 ret = 0;
U8 ret = 0;
if (style.find("NORMAL") != style.npos)
{
ret |= NORMAL;
@@ -1115,6 +1119,7 @@ LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name)
//else leave baseline
return gl_vfont_align;
}
//static
LLFontGL* LLFontGL::getFontMonospace()
{
@@ -1203,59 +1208,67 @@ LLFontGL* LLFontGL::getFontDefault()
return getFontSansSerif(); // Fallback to sans serif as default font
}
static std::string sSystemFontPath;
// static
std::string LLFontGL::getFontPathSystem()
{
std::string system_path;
if (!sSystemFontPath.empty()) return sSystemFontPath;
// Try to figure out where the system's font files are stored.
char *system_root = NULL;
#if LL_WINDOWS
system_root = getenv("SystemRoot"); /* Flawfinder: ignore */
if (!system_root)
wchar_t* pPath = nullptr;
if (SHGetKnownFolderPath(FOLDERID_Fonts, 0, nullptr, &pPath) == S_OK)
{
LL_WARNS() << "SystemRoot not found, attempting to load fonts from default path." << LL_ENDL;
}
#endif
if (system_root)
{
system_path = llformat("%s/fonts/", system_root);
sSystemFontPath = ll_convert_wide_to_string(pPath, CP_UTF8) + gDirUtilp->getDirDelimiter();
LL_INFOS() << "from SHGetKnownFolderPath(): " << sSystemFontPath << LL_ENDL;
CoTaskMemFree(pPath);
pPath = nullptr;
}
else
{
#if LL_WINDOWS
// HACK for windows 98/Me
system_path = "/WINDOWS/FONTS/";
// Try to figure out where the system's font files are stored.
auto system_root = LLStringUtil::getenv("SystemRoot");
if (! system_root.empty())
{
sSystemFontPath = gDirUtilp->add(system_root, "fonts") + gDirUtilp->getDirDelimiter();
LL_INFOS() << "from SystemRoot: " << sSystemFontPath << LL_ENDL;
}
else
{
LL_WARNS() << "SystemRoot not found, attempting to load fonts from default path." << LL_ENDL;
// HACK for windows 98/Me
sSystemFontPath = "/WINDOWS/FONTS/";
}
}
#elif LL_DARWIN
// HACK for Mac OS X
system_path = "/System/Library/Fonts/";
sSystemFontPath = "/System/Library/Fonts/";
#endif
}
return system_path;
return sSystemFontPath;
}
static std::string sLocalFontPath;
// static
std::string LLFontGL::getFontPathLocal()
{
std::string local_path;
if (!sLocalFontPath.empty()) return sLocalFontPath;
// Backup files if we can't load from system fonts directory.
// We could store this in an end-user writable directory to allow
// end users to switch fonts.
if (LLFontGL::sAppDir.length())
if (!LLFontGL::sFontDir.empty())
{
// use specified application dir to look for fonts
local_path = LLFontGL::sAppDir + "/fonts/";
sLocalFontPath = gDirUtilp->add(LLFontGL::sFontDir, "fonts") + gDirUtilp->getDirDelimiter();
}
else
{
// assume working directory is executable directory
local_path = "./fonts/";
sLocalFontPath = "./fonts/";
}
return local_path;
return sLocalFontPath;
}
LLFontGL::LLFontGL(const LLFontGL &source)

View File

@@ -214,7 +214,8 @@ public:
static F32 sScaleX;
static F32 sScaleY;
static BOOL sDisplayFont ;
static std::string sAppDir; // For loading fonts
static std::string sFontDir; // For loading fonts
private:
friend class LLFontRegistry;
friend class LLTextBillboard;
@@ -235,7 +236,6 @@ protected:
// Registry holds all instantiated fonts.
static LLFontRegistry* sFontRegistry;
};
#endif

View File

@@ -225,7 +225,7 @@ std::string currentOsName()
return "Windows";
#elif LL_DARWIN
return "Mac";
#elif LL_SDL
#elif LL_SDL || LL_MESA_HEADLESS
return "Linux";
#else
return "";
@@ -426,7 +426,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
LLFontFreetype::font_vector_t fontlist;
LLFontGL *result = NULL;
// Snarf all fonts we can into fontlistp. First will get pulled
// Snarf all fonts we can into fontlist. First will get pulled
// off the list and become the "head" font, set to non-fallback.
// Rest will consitute the fallback list.
BOOL is_first_found = TRUE;
@@ -441,7 +441,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
++file_name_it)
{
LLFontGL *fontp = new LLFontGL;
std::string font_path = local_path + *file_name_it;
std::string font_path = gDirUtilp->add(local_path, *file_name_it);
// *HACK: Fallback fonts don't render, so we can use that to suppress
// creation of OpenGL textures for test apps. JC
BOOL is_fallback = !is_first_found || !mCreateGLTextures;
@@ -449,12 +449,12 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
if (!fontp->loadFace(font_path, extra_scale * point_size,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
{
font_path = sys_path + *file_name_it;
font_path = gDirUtilp->add(sys_path, *file_name_it);
if (!fontp->loadFace(font_path, extra_scale * point_size,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
{
LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL;
LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << font_path << LL_ENDL;
delete fontp;
fontp = NULL;
}
@@ -491,6 +491,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
{
LL_WARNS() << "createFont failed in some way" << LL_ENDL;
}
mFontMap[norm_desc] = result;
return result;
}
@@ -533,19 +534,19 @@ void LLFontRegistry::destroyGL()
LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& orig_desc)
{
LLFontDescriptor norm_desc = orig_desc.normalize();
LLFontDescriptor desc = orig_desc.normalize();
font_reg_map_t::iterator it = mFontMap.find(norm_desc);
font_reg_map_t::iterator it = mFontMap.find(desc);
if (it != mFontMap.end())
return it->second;
else
{
LLFontGL *fontp = createFont(orig_desc);
LLFontGL *fontp = createFont(desc);
if (!fontp)
{
LL_WARNS() << "getFont failed, name " << orig_desc.getName()
<<" style=[" << ((S32) orig_desc.getStyle()) << "]"
<< " size=[" << orig_desc.getSize() << "]" << LL_ENDL;
LL_WARNS() << "getFont failed, name " << desc.getName()
<<" style=[" << ((S32) desc.getStyle()) << "]"
<< " size=[" << desc.getSize() << "]" << LL_ENDL;
}
return fontp;
}

View File

@@ -502,8 +502,8 @@ void LLPostProcess::destroyGL()
/*static*/void LLPostProcess::cleanupClass()
{
if(instanceExists())
getInstance()->destroyGL() ;
if (instanceExists())
deleteSingleton();
}
void LLPostProcess::copyFrameBuffer()

View File

@@ -4477,9 +4477,22 @@ void LLTextEditor::replaceUrl(const std::string &url,
{
S32 start = seg->getStart();
S32 end = seg->getEnd();
text = text.substr(0, start) + wlabel + text.substr(end, text.size() - end + 1);
seg->setEnd(start + wlabel.size());
modified = true;
const auto& old_label = text.substr(start, end - start);
if (wlabel != old_label)
{
const auto difference = std::abs((S32)wlabel.length() - (S32)old_label.length());
if (mSelectionEnd >= end) // Selection stays at/after end
{
mSelectionEnd += difference;
if (mSelectionStart >= end)
mSelectionStart += difference;
}
if (mCursorPos >= end) // Cursor stays at/after end
mCursorPos += difference;
text.replace(start, end - start, wlabel);
seg->setEnd(start + wlabel.size());
modified = true;
}
}
/* Singu TODO: Icons with Urls?
@@ -4508,7 +4521,6 @@ void LLTextEditor::replaceUrl(const std::string &url,
{
mWText = text;
mTextIsUpToDate = FALSE;
deselect();
setCursorPos(mCursorPos);
needsReflow();
}

View File

@@ -93,22 +93,7 @@ LLDir_Linux::LLDir_Linux()
#else
mAppRODataDir = tmp_str;
#endif
std::string::size_type build_dir_pos = mExecutableDir.rfind("/build-linux-");
if (build_dir_pos != std::string::npos)
{
// ...we're in a dev checkout
mSkinBaseDir = mExecutableDir.substr(0, build_dir_pos) + "/indra/newview/skins";
if (LLFile::isdir(mSkinBaseDir))
LL_INFOS() << "Running in dev checkout with mSkinBaseDir "
<< mSkinBaseDir << LL_ENDL;
else
mSkinBaseDir.clear();
}
if (mSkinBaseDir.empty())
{
// ...normal installation running
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
}
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
mOSUserDir = getCurrentUserHome(tmp_str);
mOSUserAppDir = "";

View File

@@ -149,21 +149,8 @@ LLDir_Mac::LLDir_Mac()
CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef);
CFURLRefToLLString(resourcesURLRef, mAppRODataDir, true);
size_t build_dir_pos = mExecutableDir.rfind("/indra/build-darwin-");
if (build_dir_pos != std::string::npos)
{
// ...we're in a dev checkout
mSkinBaseDir = mExecutableDir.substr(0, build_dir_pos)
+ "/indra/newview/skins";
LL_INFOS() << "Running in dev checkout with mSkinBaseDir "
<< mSkinBaseDir << LL_ENDL;
}
else
{
// ...normal installation running
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
}
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
// mOSUserDir
error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, true, &fileRef);

View File

@@ -140,18 +140,7 @@ LLDir_Win32::LLDir_Win32()
// LL_INFOS() << "mAppRODataDir = " << mAppRODataDir << LL_ENDL;
auto build_dir_pos = mExecutableDir.rfind("build-");
if (build_dir_pos != std::string::npos)
{
// ...we're in a dev checkout
mSkinBaseDir = mExecutableDir.substr(0, build_dir_pos) + "indra" + mDirDelimiter + "newview" + mDirDelimiter + "skins";
if (LLFile::isdir(mSkinBaseDir))
LL_INFOS() << "Running in dev checkout with mSkinBaseDir " << mSkinBaseDir << LL_ENDL;
else mSkinBaseDir.clear();
}
if (mSkinBaseDir.empty()) // ...normal installation running
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
// Build the default cache directory
mDefaultCacheDir = buildSLOSCacheDir();

View File

@@ -49,15 +49,18 @@ LLSplashScreen *gSplashScreenp = NULL;
BOOL gDebugClicks = FALSE;
BOOL gDebugWindowProc = FALSE;
const S32 gURLProtocolWhitelistCount = 5;
const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:", "mailto:" };
bool isWhitelistedProtocol(const std::string& escaped_url) {
// CP: added a handler list - this is what's used to open the protocol and is based on registry entry
// only meaningful difference currently is that file: protocols are opened using http:
// since no protocol handler exists in registry for file:
// Important - these lists should match - protocol to handler
// Maestro: This list isn't referenced anywhere that I could find
//const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" };
for (const auto& protocol : { "secondlife:", "http:", "https:", "data:", "mailto:" })
if (escaped_url.find(protocol) != std::string::npos)
return true;
return false;
}
S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
@@ -73,7 +76,7 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
S32 result = 0;
#if LL_MESA_HEADLESS // !!! *FIX: (???)
LL_WARNS() << "OSMessageBox: " << text << LL_ENDL;
return OSBTN_OK;
result = OSBTN_OK;
#elif LL_WINDOWS
result = OSMessageBoxWin32(text, caption, type);
#elif LL_DARWIN
@@ -249,6 +252,48 @@ BOOL LLWindow::copyTextToPrimary(const LLWString &src)
return FALSE; // fail
}
#if LL_WINDOWS
#include <shellapi.h>
#endif
int LLWindow::ShellEx(const std::string& command)
{
#if LL_WINDOWS
llutf16string url_utf16 = L'"' + utf8str_to_utf16str(command) + L'"';
SHELLEXECUTEINFO sei = { sizeof( sei ) };
sei.fMask = SEE_MASK_NOASYNC;
sei.nShow = SW_SHOWNORMAL;
sei.lpVerb = L"open";
sei.lpFile = url_utf16.c_str();
const auto& code = ShellExecuteEx(&sei) ? 0 : GetLastError();
#elif LL_DARWIN
CFURLRef urlRef;
CFStringRef stringRef = CFStringCreateWithCString(NULL, command.c_str(), kCFStringEncodingUTF8);
if (stringRef)
{
// This will succeed if the string is a full URL, including the http://
// Note that URLs specified this way need to be properly percent-escaped.
urlRef = CFURLCreateWithString(NULL, stringRef, NULL);
// Don't use CRURLCreateWithFileSystemPath -- only want valid URLs
CFRelease(stringRef);
}
OSStatus code;
if (urlRef)
{
code = LSOpenCFURLRef(urlRef, NULL);
CFRelease(urlRef);
}
else code = -1;
#else // LL_LINUX or other modern unix, pray it has xdg-open
const auto& code = std::system(("xdg-open \"" + command + '"').c_str());
#endif
if (code) LL_WARNS() << "Failed to open \"" << command << "\" return code: " << code << LL_ENDL;
return code;
}
// static
std::vector<std::string> LLWindow::getDynamicFallbackFontList()
{

View File

@@ -168,7 +168,7 @@ public:
virtual void updateLanguageTextInputArea() {}
virtual void interruptLanguageTextInput() {}
virtual void spawnWebBrowser(const std::string& escaped_url, bool async) {};
virtual void ShellEx(const std::string& command) {};
static int ShellEx(const std::string& command);
static std::vector<std::string> getDynamicFallbackFontList();
@@ -290,11 +290,7 @@ public:
//
extern BOOL gDebugWindowProc;
// Protocols, like "http" and "https" we support in URLs
extern const S32 gURLProtocolWhitelistCount;
extern const std::string gURLProtocolWhitelist[];
//extern const std::string gURLProtocolWhitelistHandler[];
bool isWhitelistedProtocol(const std::string& escaped_url);
void simpleEscapeString ( std::string& stringIn );
#endif // _LL_window_h_

File diff suppressed because it is too large Load Diff

View File

@@ -29,22 +29,23 @@
#include "llwindow.h"
#include "llwindowcallbacks.h"
#include "llwindowmacosx-objc.h"
#include "lltimer.h"
#include <Carbon/Carbon.h>
#include <AGL/agl.h>
#include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/OpenGL.h>
// AssertMacros.h does bad things.
#include "fix_macros.h"
#undef verify
#undef check
#undef require
class LLWindowMacOSX : public LLWindow
{
public:
/*virtual*/ void show();
/*virtual*/ void show(bool focus = true);
/*virtual*/ void hide();
/*virtual*/ void close();
/*virtual*/ BOOL getVisible();
@@ -60,7 +61,7 @@ public:
/*virtual*/ BOOL setPosition(LLCoordScreen position);
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size);
/*virtual*/ BOOL setSizeImpl(LLCoordWindow size);
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL);
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = nullptr);
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position);
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position);
/*virtual*/ void showCursor();
@@ -76,19 +77,18 @@ public:
/*virtual*/ BOOL isClipboardTextAvailable();
/*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst);
/*virtual*/ BOOL copyTextToClipboard(const LLWString & src);
/*virtual*/ void setWindowTitle(const std::string& title);
/*virtual*/ void flashIcon(F32 seconds);
/*virtual*/ F32 getGamma();
/*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma
/*virtual*/ U32 getFSAASamples();
/*virtual*/ void setFSAASamples(const U32 fsaa_samples);
/*virtual*/ void setVsyncMode(const S32 vsync_mode);
/*virtual*/ S32 getVsyncMode();
/*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma)
/*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; }
/*virtual*/ void gatherInput();
/*virtual*/ void delayInputProcessing() {};
/*virtual*/ void swapBuffers();
// handy coordinate space conversion routines
/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to);
/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to);
@@ -108,26 +108,34 @@ public:
/*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
/*virtual*/ void *getPlatformWindow();
/*virtual*/ void *getMediaWindow();
/*virtual*/ void bringToFront() {};
/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
/*virtual*/ void interruptLanguageTextInput();
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
/*virtual*/ void setTitle(const std::string &title);
/*virtual*/ void ShellEx(const std::string& command);
/*virtual*/ F32 getScaleFactor();
/*virtual*/ void updateUnreadCount(S32 num_conversations);
static std::vector<std::string> getDynamicFallbackFontList();
// Provide native key event data
/*virtual*/ LLSD getNativeKeyData();
void* getWindow() { return mWindow; }
LLWindowCallbacks* getCallbacks() { return mCallbacks; }
LLPreeditor* getPreeditor() { return mPreeditor; }
void updateMouseDeltas(double* deltas);
void getMouseDeltas(S32* delta);
void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action);
bool allowsLanguageInput() { return mLanguageTextInputAllowed; }
protected:
LLWindowMacOSX(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
BOOL fullscreen, BOOL clearBg, const S32 vsync_mode,
BOOL fullscreen, BOOL clearBg, S32 vsync_setting,
BOOL ignore_pixel_depth,
U32 fsaa_samples);
~LLWindowMacOSX();
@@ -148,6 +156,8 @@ protected:
BOOL shouldPostQuit() { return mPostQuit; }
private:
void restoreGLContext();
protected:
//
@@ -155,43 +165,36 @@ protected:
//
// create or re-create the GL context/window. Called from the constructor and switchContext().
BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, const S32 vsync_mode);
BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, S32 vsync_setting);
void destroyContext();
void setupFailure(const std::string& text, const std::string& caption, U32 type);
static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData);
static pascal Boolean staticMoveEventComparator( EventRef event, void* data);
OSStatus eventHandler (EventHandlerCallRef myHandler, EventRef event);
void adjustCursorDecouple(bool warpingMouse = false);
void stopDockTileBounce();
static MASK modifiersToMask(SInt16 modifiers);
static MASK modifiersToMask(S16 modifiers);
#if LL_OS_DRAGDROP_ENABLED
static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
void * handlerRefCon, DragRef theDrag);
static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
OSErr handleDragNDrop(DragRef theDrag, LLWindowCallbacks::DragNDropAction action);
//static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
//static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
#endif // LL_OS_DRAGDROP_ENABLED
//
// Platform specific variables
//
WindowRef mWindow;
AGLContext mContext;
AGLPixelFormat mPixelFormat;
CGDirectDisplayID mDisplay;
CFDictionaryRef mOldDisplayMode;
EventLoopTimerRef mTimer;
EventHandlerUPP mEventHandlerUPP;
EventHandlerRef mGlobalHandlerRef;
EventHandlerRef mWindowHandlerRef;
EventComparatorUPP mMoveEventCampartorUPP;
Rect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
Rect mPreviousWindowRect; // Save previous window for un-maximize event
Str255 mWindowTitle;
// Use generic pointers here. This lets us do some funky Obj-C interop using Obj-C objects without having to worry about any compilation problems that may arise.
NSWindowRef mWindow;
GLViewRef mGLView;
CGLContextObj mContext;
CGLPixelFormatObj mPixelFormat;
CGDirectDisplayID mDisplay;
LLRect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
std::string mWindowTitle;
double mOriginalAspectRatio;
BOOL mSimulatedRightClick;
UInt32 mLastModifiers;
U32 mLastModifiers;
BOOL mHandsOffEvents; // When true, temporarially disable CarbonEvent processing.
// Used to allow event processing when putting up dialogs in fullscreen mode.
BOOL mCursorDecoupled;
@@ -204,28 +207,18 @@ protected:
BOOL mMaximized;
BOOL mMinimized;
U32 mFSAASamples;
S32 mVsyncMode;
BOOL mForceRebuild;
S32 mDragOverrideCursor;
F32 mBounceTime;
NMRec mBounceRec;
LLTimer mBounceTimer;
S32 mDragOverrideCursor;
// Input method management through Text Service Manager.
TSMDocumentID mTSMDocument;
BOOL mLanguageTextInputAllowed;
ScriptCode mTSMScriptCode;
LangCode mTSMLangCode;
LLPreeditor* mPreeditor;
static BOOL sUseMultGL;
friend class LLWindowManager;
static WindowRef sMediaWindow;
EventRef mRawKeyEvent;
};

View File

@@ -2476,18 +2476,7 @@ void exec_cmd(const std::string& cmd, const std::string& arg)
// Must begin with protocol identifier.
void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
{
bool found = false;
S32 i;
for (i = 0; i < gURLProtocolWhitelistCount; i++)
{
if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos)
{
found = true;
break;
}
}
if (!found)
if (!isWhitelistedProtocol(escaped_url))
{
LL_WARNS() << "spawn_web_browser called for url with protocol not on whitelist: " << escaped_url << LL_ENDL;
return;

View File

@@ -3350,34 +3350,9 @@ S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 t
return retval;
}
void LLWindowWin32::ShellEx(const std::string& command)
{
LLWString url_wstring = utf8str_to_wstring( "\"" + command + "\"" );
llutf16string url_utf16 = wstring_to_utf16str( url_wstring );
SHELLEXECUTEINFO sei = { sizeof( sei ) };
sei.fMask = SEE_MASK_FLAG_DDEWAIT;
sei.nShow = SW_SHOWNORMAL;
sei.lpVerb = L"open";
sei.lpFile = url_utf16.c_str();
ShellExecuteEx( &sei );
}
void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async)
{
bool found = false;
S32 i;
for (i = 0; i < gURLProtocolWhitelistCount; i++)
{
if (escaped_url.find(gURLProtocolWhitelist[i]) == 0)
{
found = true;
break;
}
}
if (!found)
if (!isWhitelistedProtocol(escaped_url))
{
LL_WARNS("Window") << "spawn_web_browser() called for url with protocol not on whitelist: " << escaped_url << LL_ENDL;
return;
@@ -3389,25 +3364,8 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async)
// reliablly on Vista.
// this is madness.. no, this is..
LLWString url_wstring = utf8str_to_wstring( escaped_url );
llutf16string url_utf16 = wstring_to_utf16str( url_wstring );
// let the OS decide what to use to open the URL
SHELLEXECUTEINFO sei = { sizeof( sei ) };
// NOTE: this assumes that SL will stick around long enough to complete the DDE message exchange
// necessary for ShellExecuteEx to complete
if (async)
{
sei.fMask = SEE_MASK_ASYNCOK;
}
else
{
sei.fMask = SEE_MASK_FLAG_DDEWAIT;
}
sei.nShow = SW_SHOWNORMAL;
sei.lpVerb = L"open";
sei.lpFile = url_utf16.c_str();
ShellExecuteEx( &sei );
ShellEx(escaped_url);
}
void LLWindowWin32::setTitle(const std::string &title)

View File

@@ -109,7 +109,6 @@ public:
/*virtual*/ void setLanguageTextInput( const LLCoordGL & pos );
/*virtual*/ void updateLanguageTextInputArea();
/*virtual*/ void interruptLanguageTextInput();
void ShellEx(const std::string& command);
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
/*virtual*/ void setTitle(const std::string &title);

View File

@@ -1164,6 +1164,7 @@ add_custom_target(generate_viewer_version ALL
)
set_source_files_properties(
llimpanel.cpp
llversioninfo.cpp
PROPERTIES
DEPENDS generate_viewer_version # dummy dependency to force recompile every time

View File

@@ -55,11 +55,14 @@
<key>SGAllowRiggedMeshSelection</key>
<map>
<key>Comment</key>
<string>Allow selection of worn rigged meshes in build or inspect mode</string>
<string>Rigged mesh selection behavior:
0 = Never select,
1 = Hold shift to select,
2 = Hold shift or have build or inspect floater open</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
@@ -3474,6 +3477,39 @@ This should be as low as possible, but too low may break functionality</string>
<key>Value</key>
<integer>3128</integer>
</map>
<key>BrowserProxyType</key>
<map>
<key>Comment</key>
<string>Type of proxy for Web Browser</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>BrowserProxyUsername</key>
<map>
<key>Comment</key>
<string>Username for Web Proxy authentication</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string />
</map>
<key>BrowserProxyPassword</key>
<map>
<key>Comment</key>
<string>Password for Web Proxy authentication</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string />
</map>
<key>BrowserProxySocks45</key>
<map>
<key>Comment</key>
@@ -7042,7 +7078,7 @@ This should be as low as possible, but too low may break functionality</string>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>%Y-%m-%d</string>
<string>%F</string>
</map>
<key>ShortTimeFormat</key>
<map>
@@ -7053,7 +7089,7 @@ This should be as low as possible, but too low may break functionality</string>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>%H:%M</string>
<string>%R</string>
</map>
<key>LongTimeFormat</key>
<map>
@@ -7064,7 +7100,7 @@ This should be as low as possible, but too low may break functionality</string>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>%H:%M:%S</string>
<string>%T</string>
</map>
<key>TimestampFormat</key>
<map>
@@ -7075,7 +7111,7 @@ This should be as low as possible, but too low may break functionality</string>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>%a %d %b %Y %H:%M:%S</string>
<string>%a %d %b %Y %T</string>
</map>
<key>SecondsInChatAndIMs</key>
<map>

View File

@@ -927,7 +927,7 @@ RIP Latif Khalifa.</string>
<key>Type</key>
<string>String</string>
<key>Value</key>
<boolean>Default</boolean>
<string>Default</string>
</map>
<key>SinguReplaceLinks</key>
<map>
@@ -1087,6 +1087,17 @@ Changing this setting only affects new text.</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>LiruReceivedItemsNotify</key>
<map>
<key>Comment</key>
<string>Whether or not to spawn a notification in addition to the chat message when you receive items from the marketplace.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>OBJExportNotifyFailed</key>
<map>
<key>Comment</key>
@@ -1793,6 +1804,8 @@ Changing this setting only affects new text.</string>
<string>Boolean</string>
<key>Value</key>
<boolean>0</boolean>
<key>IsCOA</key>
<integer>1</integer>
</map>
<key>ToolbarVisibleMeanEvents</key>
<map>
@@ -1924,19 +1937,6 @@ Changing this setting only affects new text.</string>
<key>IsCOA</key>
<integer>1</integer>
</map>
<key>ToolbarVisibleMarketplaceListings</key>
<map>
<key>Comment</key>
<string>Whether or not the button for Marketplace Listings is on the toolbar</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<boolean>0</boolean>
<key>IsCOA</key>
<integer>1</integer>
</map>
<key>ToolbarVisibleNotificationsConsole</key>
<map>
<key>Comment</key>

View File

@@ -128,9 +128,9 @@ void LLPrefsAscentChat::onCommitTimeDate(LLUICtrl* ctrl)
if (tempTimeFormat == 0)
{
short_time = "%H:%M";
long_time = "%H:%M:%S";
timestamp = " %H:%M:%S";
short_time = "%R";
long_time = "%T";
timestamp = " %T";
}
else
{
@@ -141,7 +141,7 @@ void LLPrefsAscentChat::onCommitTimeDate(LLUICtrl* ctrl)
if (tempDateFormat == 0)
{
short_date = "%Y-%m-%d";
short_date = "%F";
long_date = "%A %d %B %Y";
timestamp = "%a %d %b %Y" + timestamp;
}
@@ -153,7 +153,7 @@ void LLPrefsAscentChat::onCommitTimeDate(LLUICtrl* ctrl)
}
else
{
short_date = "%m/%d/%Y";
short_date = "%D";
long_date = "%A, %B %d %Y";
timestamp = "%a %b %d %Y" + timestamp;
}
@@ -218,11 +218,11 @@ void LLPrefsAscentChat::refreshValues()
}
format = gSavedSettings.getString("ShortDateFormat");
if (format.find("%m/%d/%") != std::string::npos)
if (format.find("%D") != std::string::npos || format.find("%m/%d/%") != std::string::npos)
{
mDateFormat = 2;
}
else if (format.find("%d/%m/%") != -1)
else if (format.find("%d/%m/%") != std::string::npos)
{
mDateFormat = 1;
}

View File

@@ -632,7 +632,7 @@ bool cmd_line_chat(std::string data, EChatType type)
// even if they are out of draw distance.
LLUUID cmdline_partial_name2key(std::string partial_name)
{
std::vector<LLUUID> avatars;
uuid_vec_t avatars;
std::string av_name;
LLStringUtil::toLower(partial_name);
LLWorld::getInstance()->getAvatars(&avatars);

View File

@@ -77,7 +77,7 @@ public:
};
typedef std::vector<std::pair<LLViewerObject*,std::string> > obj_info_t;
typedef std::vector<LLUUID> id_list_t;
typedef uuid_vec_t id_list_t;
typedef std::vector<std::string> string_list_t;
typedef std::vector<S32> int_list_t;
typedef std::vector<MaterialInfo> material_list_t;

Binary file not shown.

View File

@@ -109,7 +109,7 @@ void HippoGridInfo::setPlatform(const std::string& platform)
{
setPlatform(PLATFORM_WHITECORE);
}
else if (tmp == "opensim")
else if (tmp == "opensim" || tmp == "halcyon")
{
setPlatform(PLATFORM_OPENSIM);
}

View File

@@ -217,7 +217,7 @@ void JCFloaterAreaSearch::results()
LLUUID object_id = objectp->getID();
if(!requestIfNeeded(object_id))
{
std::map<LLUUID,ObjectData>::iterator it = mCachedObjects.find(object_id);
auto it = mCachedObjects.find(object_id);
if(it != mCachedObjects.end())
{
//LL_INFOS() << "all entries are \"\" or we have data" << LL_ENDL;
@@ -281,7 +281,7 @@ void JCFloaterAreaSearch::processObjectPropertiesFamily(LLMessageSystem* msg, vo
LLUUID object_id;
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, object_id);
std::set<LLUUID>::iterator it = floater->mPendingObjects.find(object_id);
auto it = floater->mPendingObjects.find(object_id);
if(it != floater->mPendingObjects.end())
floater->mPendingObjects.erase(it);
//else if(floater->mCachedObjects.count(object_id)) //Let entries update.

View File

@@ -38,6 +38,7 @@
#include "lluuid.h"
#include "llstring.h"
#include "llframetimer.h"
#include <boost/unordered_map.hpp>
class LLTextBox;
class LLScrollListCtrl;
@@ -91,8 +92,8 @@ private:
LLUUID owner_id;
LLUUID group_id;
};
std::set<LLUUID> mPendingObjects;
std::map<LLUUID, ObjectData> mCachedObjects;
uuid_set_t mPendingObjects;
boost::unordered_map<LLUUID, ObjectData> mCachedObjects;
std::string mFilterStrings[LIST_OBJECT_COUNT];
};

View File

@@ -948,7 +948,7 @@ void lggHunSpell_Wrapper::editCustomButton()
//glggHunSpell->addWordToCustomDictionary("temp");
}
gViewerWindow->getWindow()->ShellEx(dicdicpath);
LLWindow::ShellEx(dicdicpath);
}
void lggHunSpell_Wrapper::setSpellCheckHighlight(BOOL highlight)

Some files were not shown because too many files have changed in this diff Show More