Merge in viewer-development

master
simon@Simon-PC.lindenlab.com 2012-07-31 15:42:02 -07:00
commit 83f5d0c616
373 changed files with 33222 additions and 8884 deletions

View File

@ -25,6 +25,7 @@ indra/lib/mono/indra/*.exe
indra/lib/mono/indra/*.pdb
indra/lib/python/eventlet/
indra/llwindow/glh/glh_linear.h
indra/newview/app_settings/dictionaries
indra/newview/app_settings/mozilla
indra/newview/app_settings/mozilla-runtime-*
indra/newview/app_settings/mozilla_debug

32
.hgtags
View File

@ -150,6 +150,7 @@ a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1
e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
2a3965b3ad202df7ea25d2be689291bb14a1280e DRTVWR-155
6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
@ -264,6 +265,7 @@ c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
16f8e2915f3f2e4d732fb3125daf229cb0fd1875 DRTVWR-114_3.2.8-beta1
37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
16f8e2915f3f2e4d732fb3125daf229cb0fd1875 3.2.8-beta1
089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
987425b1acf4752379b2e1eb20944b4b35d67a85 DRTVWR-115_3.2.8-beta2
987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
51b2fd52e36aab8f670e0874e7e1472434ec4b4a DRTVWR-113_3.2.8-release
@ -286,6 +288,9 @@ d5f263687f43f278107363365938f0a214920a4b 3.3.0-beta1
28b95a6a28dca3338d9a1f4f204b96678df9f6a5 viewer-beta-candidate
b43cd25be49e3984ff5361cefad020e069131d98 3.3.1-start
3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 DRTVWR-125
dffd0457ee0745de65bf95f0642a5c9e46b8e2f0 viewer-beta-candidate
3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 viewer-beta-candidate
3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 viewer-beta-candidate
3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 3.3.1-start
28b95a6a28dca3338d9a1f4f204b96678df9f6a5 3.3.1-beta1
1dc545e44617975da2a4a32fe303386c687a6ca1 viewer-beta-candidate
@ -300,7 +305,13 @@ c623bbc854b6f7ee1b33a3718f76715046aa2937 viewer-release-candidate
675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate
675668bd24d3bea570814f71762a2a806f7e1b8d 3.3.2-release
675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate
050e48759337249130f684b4a21080b683f61732 DRTVWR-168
b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171
c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153
15e90b52dc0297921b022b90d10d797436b8a1bd viewer-release-candidate
6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148
@ -317,3 +328,24 @@ fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2
af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169
4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3
6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release
57d221de3df94f90b55204313c2cef044a3c0ae2 DRTVWR-176
09ef7fd1b0781f33b8a3a9af6236b7bcb4831910 DRTVWR-170
005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 3.3.4-beta1
f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 DRTVWR-158
f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 3.3.4-beta1
cbea6356ce9cb0c313b6777f10c5c14783264fcc DRTVWR-174
bce218b2b45b730b22cc51e4807aa8b571cadef3 DRTVWR-173
f91d003091a61937a044652c4c674447f7dcbb7a 3.3.4-beta1
82b5330bc8b17d0d4b598832e9c5a92e90075682 3.3.4-beta2
eb539c65e6ee26eea2bf373af2d0f4b52dc91289 DRTVWR-177
4ad8a3afe40e0200309e3ada68932c4295ac2795 DRTVWR-179
a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3
4281aa899fb2cedb7a9ca7ce91c5c29d4aa69594 DRTVWR-180
9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184
5c08e1d8edd871807153603b690e3ee9dbb548aa DRTVWR-183
6c75f220b103db1420919c8b635fe53e2177f318 3.3.4-beta4
ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release
a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182
1f27cdfdc54246484f8afbbe42ce48e954175cbd 3.4.0-beta1

View File

@ -18,7 +18,7 @@ build_CYGWIN_Debug = false
email_status_this_is_os = true
# Limit extent of codeticket updates to revisions after...
codeticket_since = 2.2.0-release
codeticket_since = 3.3.0-release
# ========================================
# Viewer Development
@ -43,18 +43,20 @@ integration_viewer-development.viewer_channel = "Second Life Development"
integration_viewer-development.login_channel = "Second Life Development"
integration_viewer-development.build_viewer_update_version_manager = false
integration_viewer-development.email = viewer-development-builds@lists.secondlife.com
integration_viewer-development.build_enforce_coding_policy = true
integration_viewer-development.codeticket_add_context = true
integration_viewer-development.build_enforce_coding_policy = false
integration_viewer-development.codeticket_add_context = false
viewer-beta.viewer_channel = "Second Life Beta Viewer"
viewer-beta.login_channel = "Second Life Beta Viewer"
viewer-beta.build_debug_release_separately = true
viewer-beta.build_viewer_update_version_manager = true
viewer-beta.codeticket_add_context = false
viewer-release.viewer_channel = "Second Life Release"
viewer-release.login_channel = "Second Life Release"
viewer-release.build_debug_release_separately = true
viewer-release.build_viewer_update_version_manager = true
viewer-release.codeticket_add_context = false
# ========================================
# mesh-development
@ -112,31 +114,27 @@ viewer-mesh.login_channel = "Project Viewer - Mesh"
viewer-mesh.viewer_grid = aditi
viewer-mesh.email = shining@lists.lindenlab.com
# ================
# oz
# ================
# ========================================
# viewer-adult-check
# ========================================
Snowstorm_viewer-project-review.build_debug_release_separately = true
Snowstorm_viewer-project-review.codeticket_add_context = true
Snowstorm_viewer-project-review.viewer_channel = "Project Viewer - Snowstorm Team"
Snowstorm_viewer-project-review.login_channel = "Project Viewer - Snowstorm Team"
Snowstorm_viewer-project-review.codeticket_add_context = true
viewer-adult-check.viewer_channel = "Project Viewer - AdultCheck"
viewer-adult-check.login_channel = "Project Viewer - AdultCheck"
viewer-adult-check.viewer_grid = agni
viewer-adult-check.build_debug_release_separately = true
viewer-adult-check.build_CYGWIN_Debug = false
viewer-adult-check.build_viewer_update_version_manager = false
oz_viewer-devreview.build_debug_release_separately = true
oz_viewer-devreview.codeticket_add_context = false
oz_viewer-devreview.build_enforce_coding_policy = true
oz_viewer-devreview.email = oz@lindenlab.com
# ========================================
# viewer-pathfinding
# ========================================
oz_viewer-trial.build_debug_release_separately = true
oz_viewer-trial.codeticket_add_context = false
oz_viewer-trial.build_enforce_coding_policy = true
oz_viewer-trial.email = oz@lindenlab.com
oz_viewer-beta-review.build_debug_release_separately = true
oz_viewer-beta-review.codeticket_add_context = false
oz_viewer-beta-review.viewer_channel = "Second Life Beta Viewer"
oz_viewer-beta-review.login_channel = "Second Life Beta Viewer"
oz_viewer-beta-review.email = oz@lindenlab.com
viewer-pathfinding.viewer_channel = "Project Viewer - Pathfinding"
viewer-pathfinding.login_channel = "Project Viewer - Pathfinding"
viewer-pathfinding.viewer_grid = agni
viewer-pathfinding.build_debug_release_separately = true
viewer-pathfinding.build_CYGWIN_Debug = false
viewer-pathfinding.build_viewer_update_version_manager = false
# =================================================================
# asset delivery 2010 projects

View File

@ -363,6 +363,54 @@
</map>
</map>
</map>
<key>dictionaries</key>
<map>
<key>license</key>
<string>various open</string>
<key>license_file</key>
<string>LICENSES/dictionaries.txt</string>
<key>name</key>
<string>dictionaries</string>
<key>platforms</key>
<map>
<key>darwin</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>06a6c49eb1873e95623d3d2d07aee903</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/Darwin/installer/dictionaries-1-darwin-20120616.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
</map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>4f0ca21d27e0cd0b002149062b0a4b25</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/Linux/installer/dictionaries-1-linux-20120616.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>7520d75f6af325328322201c888191d4</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/CYGWIN/installer/dictionaries-1-windows-20120616.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
</map>
<key>elfio</key>
<map>
<key>license</key>
@ -855,6 +903,54 @@
</map>
</map>
</map>
<key>havok-source</key>
<map>
<key>license</key>
<string>havok-ares</string>
<key>license_file</key>
<string>LICENSES/havok.txt</string>
<key>name</key>
<string>havok-source</string>
<key>platforms</key>
<map>
<key>darwin</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>efaf5cb3e861d44518eb03f4c406f03c</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/falcon_3p-havok-source/rev/261536/arch/Darwin/installer/havok_source-2012.1-darwin-20120710.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
</map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>50037fff3fd3356a073cdae88348c9ab</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/falcon_3p-havok-source/rev/261536/arch/Linux/installer/havok_source-2012.1-linux-20120711.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>cd6638f5a03469654615730c16889a60</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/falcon_3p-havok-source/rev/261536/arch/CYGWIN/installer/havok_source-2012.1-windows-20120710.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
</map>
<key>jpeglib</key>
<map>
<key>license</key>
@ -999,6 +1095,54 @@
</map>
</map>
</map>
<key>libhunspell</key>
<map>
<key>license</key>
<string>libhunspell</string>
<key>license_file</key>
<string>LICENSES/hunspell.txt</string>
<key>name</key>
<string>libhunspell</string>
<key>platforms</key>
<map>
<key>darwin</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>6f5db0ef258df6e5c93c843ec559db6d</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/Darwin/installer/libhunspell-1.3.2-darwin-20120616.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
</map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>0c432d2626aea2e91a56335879c92965</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/Linux/installer/libhunspell-1.3.2-linux-20120616.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>6a140e5620826aa5e587b4157f57b389</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/CYGWIN/installer/libhunspell-1.3.2-windows-20120616.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
</map>
<key>libpng</key>
<map>
<key>license</key>
@ -1095,14 +1239,14 @@
</map>
</map>
</map>
<key>llconvexdecomposition</key>
<key>llphysicsextensions_source</key>
<map>
<key>license</key>
<string>havok</string>
<string>TEMPORARY</string>
<key>license_file</key>
<string>on_file</string>
<string>LICENSES/llphysicsextensions.txt</string>
<key>name</key>
<string>llconvexdecomposition</string>
<string>llphysicsextensions_source</string>
<key>platforms</key>
<map>
<key>darwin</key>
@ -1110,9 +1254,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>362654a472ef7368d4c803ae3fb89d95</string>
<string>de22a97b276913a6dd05838b7fe297af</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/Darwin/installer/llconvexdecomposition-0.1-darwin-20110819.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/262536/arch/Darwin/installer/llphysicsextensions_source-0.3-darwin-20120725.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1122,9 +1268,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>c7801d899daec5338fbe95053255b7e7</string>
<string>d2dfbbc11aac34ebd551df86524c8c9c</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/Linux/installer/llconvexdecomposition-0.1-linux-20110819.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/262536/arch/Linux/installer/llphysicsextensions_source-0.3-linux-20120725.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1134,23 +1280,25 @@
<key>archive</key>
<map>
<key>hash</key>
<string>6ecf2f85f03c5ae87fe45769566a5660</string>
<string>99abccc5d117ab82cadb8cff0d85b867</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/CYGWIN/installer/llconvexdecomposition-0.1-windows-20110819.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/262536/arch/CYGWIN/installer/llphysicsextensions_source-0.3-windows-20120725.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>0.2</string>
</map>
<key>llconvexdecompositionstub</key>
<key>llphysicsextensions_stub</key>
<map>
<key>license</key>
<string>lgpl</string>
<string>TEMPORARY</string>
<key>license_file</key>
<string>LICENSES/LLConvexDecompositionStubLicense.txt</string>
<string>LICENSES/llphysicsextensions.txt</string>
<key>name</key>
<string>llconvexdecompositionstub</string>
<string>llphysicsextensions_stub</string>
<key>platforms</key>
<map>
<key>darwin</key>
@ -1158,9 +1306,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>a5f53e09f67271fd50f1131ffdda9d27</string>
<string>3528620230fbd288fcc9dbbd8d8a6b59</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/Darwin/installer/llconvexdecompositionstub-0.3-darwin-20110819.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub/rev/262536/arch/Darwin/installer/llphysicsextensions_stub-0.3-darwin-20120725.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1170,9 +1320,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>0006a964f1497f55a5f181b7042d2d22</string>
<string>69d188f72f9494b0e74c94ca0496f618</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/Linux/installer/llconvexdecompositionstub-0.3-linux-20110819.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub/rev/262536/arch/Linux/installer/llphysicsextensions_stub-0.3-linux-20120725.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1182,14 +1332,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>b859e7e3bb03ebb467f0309f46422995</string>
<string>61fc2b84ad53cf8d98d1784c31f9928e</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/CYGWIN/installer/llconvexdecompositionstub-0.3-windows-20110819.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub/rev/262536/arch/CYGWIN/installer/llphysicsextensions_stub-0.3-windows-20120725.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>0.2</string>
</map>
<key>llqtwebkit</key>
<map>
@ -1762,8 +1914,12 @@
</map>
<key>package_description</key>
<map>
<key>description</key>
<string>Spell checking dictionaries</string>
<key>license</key>
<string>various open</string>
<key>name</key>
<string>viewer_development</string>
<string>dictionaries</string>
<key>platforms</key>
<map>
<key>common</key>
@ -2473,6 +2629,8 @@
<string>windows</string>
</map>
</map>
<key>version</key>
<string>1.0</string>
</map>
<key>type</key>
<string>autobuild</string>

View File

@ -15,6 +15,12 @@
# * The basic convention is that the build name can be mapped onto a mercurial URL,
# which is also used as the "branch" name.
check_for()
{
if [ -e "$2" ]; then found_dict='FOUND'; else found_dict='MISSING'; fi
echo "$1 ${found_dict} '$2' " 1>&2
}
build_dir_Darwin()
{
echo build-darwin-i386
@ -59,6 +65,8 @@ pre_build()
&& [ -r "$master_message_template_checkout/message_template.msg" ] \
&& template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
check_for "Before 'autobuild configure'" ${build_dir}/packages/dictionaries
"$AUTOBUILD" configure -c $variant -- \
-DPACKAGE:BOOL=ON \
-DRELEASE_CRASH_REPORTING:BOOL=ON \
@ -67,7 +75,33 @@ pre_build()
-DGRID:STRING="\"$viewer_grid\"" \
-DLL_TESTS:BOOL="$run_tests" \
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url
end_section "Pre$variant"
check_for "After 'autobuild configure'" ${build_dir}/packages/dictionaries
end_section "Pre$variant"
}
package_llphysicsextensions_tpv()
{
begin_section "PhysicsExtensions_TPV"
tpv_status=0
if [ "$variant" = "Release" ]
then
llpetpvcfg=$build_dir/packages/llphysicsextensions/autobuild-tpv.xml
"$AUTOBUILD" build --verbose --config-file $llpetpvcfg -c Tpv
# capture the package file name for use in upload later...
PKGTMP=`mktemp -t pgktpv.XXXXXX`
trap "rm $PKGTMP* 2>/dev/null" 0
"$AUTOBUILD" package --verbose --config-file $llpetpvcfg > $PKGTMP
tpv_status=$?
sed -n -e 's/^wrote *//p' $PKGTMP > $build_dir/llphysicsextensions_package
else
echo "Do not provide llphysicsextensions_tpv for $variant"
llphysicsextensions_package=""
fi
end_section "PhysicsExtensions_TPV"
return $tpv_status
}
build()
@ -76,13 +110,21 @@ build()
if $build_viewer
then
begin_section "Viewer$variant"
if "$AUTOBUILD" build --no-configure -c $variant
check_for "Before 'autobuild build'" ${build_dir}/packages/dictionaries
"$AUTOBUILD" build --no-configure -c $variant
viewer_build_ok=$?
end_section "Viewer$variant"
package_llphysicsextensions_tpv
tpvlib_build_ok=$?
if [ $viewer_build_ok -eq 0 -a $tpvlib_build_ok -eq 0 ]
then
echo true >"$build_dir"/build_ok
else
echo false >"$build_dir"/build_ok
fi
end_section "Viewer$variant"
check_for "After 'autobuild configure'" ${build_dir}/packages/dictionaries
fi
}
@ -172,7 +214,10 @@ eval "$("$AUTOBUILD" source_environment)"
# dump environment variables for debugging
env|sort
check_for "Before 'autobuild install'" ${build_dir}/packages/dictionaries
check_for "After 'autobuild install'" ${build_dir}/packages/dictionaries
# Now run the build
succeeded=true
build_processes=
@ -196,11 +241,6 @@ do
mkdir -p "$build_dir"
mkdir -p "$build_dir/tmp"
# Install packages.
begin_section "AutobuildInstall"
"$AUTOBUILD" install --verbose --skip-license-check
end_section "AutobuildInstall"
if pre_build "$variant" "$build_dir" >> "$build_log" 2>&1
then
if $build_link_parallel
@ -270,13 +310,25 @@ then
upload_item quicklink "$package" binary/octet-stream
[ -f summary.json ] && upload_item installer summary.json text/plain
# Upload crash reporter files.
case "$last_built_variant" in
Release)
# Upload crash reporter files
for symbolfile in $symbolfiles
do
upload_item symbolfile "$build_dir/$symbolfile" binary/octet-stream
done
# Upload the llphysicsextensions_tpv package, if one was produced
if [ -r "$build_dir/llphysicsextensions_package" ]
then
llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
upload_item private_artifact "$llphysicsextensions_package" binary/octet-stream
else
echo "No llphysicsextensions_package"
fi
;;
*)
echo "Skipping mapfile for $last_built_variant"
;;
esac

View File

@ -297,6 +297,8 @@ Cherry Cheevers
ChickyBabes Zuzu
Christopher Organiser
Ciaran Laval
Cinder Roxley
STORM-1703
Clara Young
Coaldust Numbers
VWR-1095
@ -471,6 +473,7 @@ Hiro Sommambulist
VWR-143
Hitomi Tiponi
STORM-1741
STORM-1862
Holger Gilruth
Horatio Freund
Hoze Menges
@ -623,12 +626,22 @@ Jonathan Yap
STORM-1799
STORM-1796
STORM-1807
STORM-1812
STORM-1820
STORM-1839
STORM-1842
STORM-1808
STORM-637
STORM-1822
STORM-1809
STORM-1793
STORM-1810
STORM-1860
STORM-1852
STORM-1870
STORM-1872
STORM-1858
STORM-1862
Kadah Coba
STORM-1060
Jondan Lundquist
@ -725,6 +738,8 @@ Marc2 Sands
Marianne McCann
Marine Kelley
STORM-281
MartinRJ Fayray
STORM-1845
Matthew Anthony
Matthew Dowd
VWR-1344
@ -1052,6 +1067,8 @@ Simon Nolan
Sini Nubalo
Sitearm Madonna
SLB Wirefly
Slee Mayo
SEC-1075
snowy Sidran
SpacedOut Frye
VWR-34
@ -1287,6 +1304,7 @@ Zi Ree
VWR-24017
VWR-25588
STORM-1790
STORM-1842
Zipherius Turas
VWR-76
VWR-77

View File

@ -546,8 +546,24 @@
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
<!-- UDPDeprecated Messages -->
<key>NavMeshStatusUpdate</key>
<map>
<key>flavor</key>
<string>llsd</string>
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
<key>AgentStateUpdate</key>
<map>
<key>flavor</key>
<string>llsd</string>
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
<!-- UDPDeprecated Messages -->
<key>ScriptRunningReply</key>
<map>
<key>flavor</key>

View File

@ -37,12 +37,12 @@ set(cmake_SOURCE_FILES
GLOD.cmake
GStreamer010Plugin.cmake
GooglePerfTools.cmake
Hunspell.cmake
JPEG.cmake
LLAddBuildTest.cmake
LLAudio.cmake
LLCharacter.cmake
LLCommon.cmake
LLConvexDecomposition.cmake
LLCrashLogger.cmake
LLDatabase.cmake
LLImage.cmake
@ -53,6 +53,7 @@ set(cmake_SOURCE_FILES
LLMessage.cmake
LLPlugin.cmake
LLPrimitive.cmake
LLPhysicsExtensions.cmake
LLRender.cmake
LLScene.cmake
LLTestCommand.cmake

View File

@ -41,6 +41,7 @@ if(WINDOWS)
libeay32.dll
libcollada14dom22-d.dll
glod.dll
libhunspell.dll
)
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
@ -53,12 +54,13 @@ if(WINDOWS)
libeay32.dll
libcollada14dom22.dll
glod.dll
libhunspell.dll
)
if(USE_GOOGLE_PERFTOOLS)
if(USE_TCMALLOC)
set(debug_files ${debug_files} libtcmalloc_minimal-debug.dll)
set(release_files ${release_files} libtcmalloc_minimal.dll)
endif(USE_GOOGLE_PERFTOOLS)
endif(USE_TCMALLOC)
if (FMOD)
set(debug_files ${debug_files} fmod.dll)
@ -212,11 +214,12 @@ elseif(DARWIN)
libexpat.1.5.2.dylib
libexpat.dylib
libGLOD.dylib
libllqtwebkit.dylib
libminizip.a
libllqtwebkit.dylib
libminizip.a
libndofdev.dylib
libhunspell-1.3.0.dylib
libexception_handler.dylib
libcollada14dom.dylib
libcollada14dom.dylib
)
# fmod is statically linked on darwin
@ -257,24 +260,28 @@ elseif(LINUX)
libdb-5.1.so
libexpat.so
libexpat.so.1
libglod.so
libglod.so
libgmock_main.so
libgmock.so.0
libgmodule-2.0.so
libgobject-2.0.so
libgtest_main.so
libgtest.so.0
libminizip.so
libhunspell-1.3.so.0.0.0
libminizip.so
libopenal.so
libopenjpeg.so
libssl.so
libtcmalloc_minimal.so
libuuid.so.16
libuuid.so.16.0.22
libssl.so.1.0.0
libfontconfig.so.1.4.4
)
if (USE_TCMALLOC)
set(release_files ${release_files} "libtcmalloc_minimal.so")
endif (USE_TCMALLOC)
if (FMOD)
set(release_files ${release_files} "libfmod-3.75.so")
endif (FMOD)

View File

@ -0,0 +1,38 @@
# -*- cmake -*-
# - Find HUNSPELL
# This module defines
# HUNSPELL_INCLUDE_DIR, where to find libhunspell.h, etc.
# HUNSPELL_LIBRARY, the library needed to use HUNSPELL.
# HUNSPELL_FOUND, If false, do not try to use HUNSPELL.
find_path(HUNSPELL_INCLUDE_DIR hunspell.h
PATH_SUFFIXES hunspell
)
set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3.0 libhunspell)
find_library(HUNSPELL_LIBRARY
NAMES ${HUNSPELL_NAMES}
)
if (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
set(HUNSPELL_FOUND "YES")
else (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
set(HUNSPELL_FOUND "NO")
endif (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
if (HUNSPELL_FOUND)
if (NOT HUNSPELL_FIND_QUIETLY)
message(STATUS "Found Hunspell: Library in '${HUNSPELL_LIBRARY}' and header in '${HUNSPELL_INCLUDE_DIR}' ")
endif (NOT HUNSPELL_FIND_QUIETLY)
else (HUNSPELL_FOUND)
if (HUNSPELL_FIND_REQUIRED)
message(FATAL_ERROR " * * *\nCould not find HUNSPELL library! * * *")
endif (HUNSPELL_FIND_REQUIRED)
endif (HUNSPELL_FOUND)
mark_as_advanced(
HUNSPELL_LIBRARY
HUNSPELL_INCLUDE_DIR
)

View File

@ -1,20 +1,34 @@
# -*- cmake -*-
include(Prebuilt)
# If you want to enable or disable TCMALLOC in viewer builds, this is the place.
# set ON or OFF as desired.
set (USE_TCMALLOC ON)
if (STANDALONE)
include(FindGooglePerfTools)
else (STANDALONE)
if (WINDOWS)
use_prebuilt_binary(tcmalloc)
set(TCMALLOC_LIBRARIES
debug libtcmalloc_minimal-debug
optimized libtcmalloc_minimal)
if (USE_TCMALLOC)
use_prebuilt_binary(tcmalloc)
set(TCMALLOC_LIBRARIES
debug libtcmalloc_minimal-debug
optimized libtcmalloc_minimal)
set(TCMALLOC_LINK_FLAGS "/INCLUDE:__tcmalloc")
else (USE_TCMALLOC)
set(TCMALLOC_LIBRARIES)
set(TCMALLOC_LINK_FLAGS)
endif (USE_TCMALLOC)
set(GOOGLE_PERFTOOLS_FOUND "YES")
endif (WINDOWS)
if (LINUX)
use_prebuilt_binary(tcmalloc)
set(TCMALLOC_LIBRARIES
tcmalloc)
if (USE_TCMALLOC)
use_prebuilt_binary(tcmalloc)
set(TCMALLOC_LIBRARIES
tcmalloc)
else (USE_TCMALLOC)
set(TCMALLOC_LIBRARIES)
endif (USE_TCMALLOC)
set(PROFILER_LIBRARIES profiler)
set(GOOGLE_PERFTOOLS_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include)
@ -29,13 +43,19 @@ if (GOOGLE_PERFTOOLS_FOUND)
endif (GOOGLE_PERFTOOLS_FOUND)
if (WINDOWS)
set(USE_GOOGLE_PERFTOOLS ON)
set(USE_GOOGLE_PERFTOOLS ON)
endif (WINDOWS)
if (USE_GOOGLE_PERFTOOLS)
set(TCMALLOC_FLAG -ULL_USE_TCMALLOC=1)
if (USE_TCMALLOC)
set(TCMALLOC_FLAG -DLL_USE_TCMALLOC=1)
else (USE_TCMALLOC)
set(TCMALLOC_FLAG -ULL_USE_TCMALLOC)
endif (USE_TCMALLOC)
endif (USE_GOOGLE_PERFTOOLS)
if (USE_GOOGLE_PERFTOOLS)
include_directories(${GOOGLE_PERFTOOLS_INCLUDE_DIR})
set(GOOGLE_PERFTOOLS_LIBRARIES ${TCMALLOC_LIBRARIES} ${STACKTRACE_LIBRARIES} ${PROFILER_LIBRARIES})
else (USE_GOOGLE_PERFTOOLS)
set(TCMALLOC_FLAG -ULL_USE_TCMALLOC)
endif (USE_GOOGLE_PERFTOOLS)

83
indra/cmake/Havok.cmake Normal file
View File

@ -0,0 +1,83 @@
# -*- cmake -*-
use_prebuilt_binary(havok-source)
set(Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Source)
list(APPEND Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Demo)
set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
if (LL_DEBUG_HAVOK)
if (WIN32)
# Always link relwithdebinfo to havok-hybrid on windows.
set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
else (WIN32)
set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
endif (WIN32)
else (LL_DEBUG_HAVOK)
set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
endif (LL_DEBUG_HAVOK)
set(HAVOK_LIBS
hkBase
hkCompat
hkGeometryUtilities
hkInternal
hkSerialize
hkSceneData
hkpCollide
hkpUtilities
hkpConstraintSolver
hkpDynamics
hkpInternal
hkaiInternal
hkaiPathfinding
hkaiAiPhysicsBridge
hkcdInternal
hkcdCollide
hkpVehicle
hkVisualize
hkaiVisualize
hkgpConvexDecomposition
)
unset(HK_DEBUG_LIBRARIES)
unset(HK_RELEASE_LIBRARIES)
unset(HK_RELWITHDEBINFO_LIBRARIES)
foreach(HAVOK_LIB ${HAVOK_LIBS})
find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
if(LINUX)
set(cmd "mkdir")
set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
set(cmd "ar")
set(arg " -xv")
set(arg "${arg} ../lib${HAVOK_LIB}.a")
exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
file(GLOB extracted_debug "${debug_dir}/*.o")
file(GLOB extracted_release "${release_dir}/*.o")
file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
else(LINUX)
# Win32
list(APPEND HK_DEBUG_LIBRARIES ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
endif (LINUX)
endforeach(HAVOK_LIB)

View File

@ -0,0 +1,22 @@
# -*- cmake -*-
include(Prebuilt)
set(HUNSPELL_FIND_QUIETLY ON)
set(HUNSPELL_FIND_REQUIRED ON)
if (STANDALONE)
include(FindHUNSPELL)
else (STANDALONE)
use_prebuilt_binary(libhunspell)
if (WINDOWS)
set(HUNSPELL_LIBRARY libhunspell)
elseif(DARWIN)
set(HUNSPELL_LIBRARY hunspell-1.3.0)
elseif(LINUX)
set(HUNSPELL_LIBRARY hunspell-1.3)
else()
message(FATAL_ERROR "Invalid platform")
endif()
set(HUNSPELL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/hunspell)
use_prebuilt_binary(dictionaries)
endif (STANDALONE)

View File

@ -205,6 +205,15 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
endif(STANDALONE)
if (WINDOWS)
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname}
PROPERTIES
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS}"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
LINK_FLAGS_RELEASE ""
)
endif (WINDOWS)
# Add link deps to the executable
if(TEST_DEBUG)
message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")

View File

@ -1,12 +0,0 @@
# -*- cmake -*-
include(Prebuilt)
set(LLCONVEXDECOMP_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
if (INSTALL_PROPRIETARY AND NOT STANDALONE)
use_prebuilt_binary(llconvexdecomposition)
set(LLCONVEXDECOMP_LIBRARY llconvexdecomposition)
else (INSTALL_PROPRIETARY AND NOT STANDALONE)
use_prebuilt_binary(llconvexdecompositionstub)
set(LLCONVEXDECOMP_LIBRARY llconvexdecompositionstub)
endif (INSTALL_PROPRIETARY AND NOT STANDALONE)

View File

@ -0,0 +1,35 @@
# -*- cmake -*-
include(Prebuilt)
# There are three possible solutions to provide the llphysicsextensions:
# - The full source package, selected by -DHAVOK:BOOL=ON
# - The stub source package, selected by -DHAVOK:BOOL=OFF
# - The prebuilt package available to those with sublicenses, selected by -DHAVOK_TPV:BOOL=ON
if (INSTALL_PROPRIETARY)
set(HAVOK ON CACHE BOOL "Use Havok physics library")
endif (INSTALL_PROPRIETARY)
# Note that the use_prebuilt_binary macros below do not in fact include binaries;
# the llphysicsextensions_* packages are source only and are built here.
# The source package and the stub package both build libraries of the same name.
if (HAVOK)
include(Havok)
use_prebuilt_binary(llphysicsextensions_source)
set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/src)
set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensions)
elseif (HAVOK_TPV)
use_prebuilt_binary(llphysicsextensions_tpv)
set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensions_tpv)
else (HAVOK)
use_prebuilt_binary(llphysicsextensions_stub)
set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub)
set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensionsstub)
endif (HAVOK)
set(LLPHYSICSEXTENSIONS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)

View File

@ -38,9 +38,8 @@ if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
# packages/lib/release directory to deal with autobuild packages that don't
# provide (e.g.) lib/debug libraries.
list(APPEND AUTOBUILD_LIBS_INSTALL_DIRS ${ARCH_PREBUILT_DIRS_RELEASE})
message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}, extending AUTOBUILD_LIBS_INSTALL_DIRS")
endif (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
message(STATUS "For ${CMAKE_BUILD_TYPE}, AUTOBUILD_LIBS_INSTALL_DIRS: ${AUTOBUILD_LIBS_INSTALL_DIRS}")
link_directories(${AUTOBUILD_LIBS_INSTALL_DIRS})
if (LINUX)

View File

@ -101,8 +101,8 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# To support a different SDK update these Xcode settings:
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.0")
set(CMAKE_OSX_SYSROOT macosx10.6)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:

View File

@ -2,15 +2,9 @@
include(Prebuilt)
if (NOT STANDALONE)
use_prebuilt_binary(libhunspell)
use_prebuilt_binary(libuuid)
use_prebuilt_binary(slvoice)
use_prebuilt_binary(fontconfig)
endif(NOT STANDALONE)
if(VIEWER AND NOT STANDALONE)
if(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
message(STATUS "We seem to have an artwork bundle in the tree - brilliant.")
else(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
message(FATAL_ERROR "Didn't find an artwork bundle - this needs to be downloaded separately and unpacked into this tree. You can probably get it from the same place you got your viewer source. Thanks!")
endif(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
endif(VIEWER AND NOT STANDALONE)

View File

@ -18,6 +18,7 @@ include(LLWindow)
include(LLUI)
include(LLVFS) # ugh, needed for LLDir
include(LLXML)
include(Hunspell)
include(Linking)
# include(Tut)
@ -31,6 +32,7 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LIBS_PREBUILD_DIR}/include/hunspell
)
set(llui_libtest_SOURCE_FILES
@ -78,6 +80,7 @@ target_link_libraries(llui_libtest
${LLIMAGEJ2COJ_LIBRARIES}
${OS_LIBRARIES}
${GOOGLE_PERFTOOLS_LIBRARIES}
${HUNSPELL_LIBRARY}
)
if (WINDOWS)

View File

@ -27,7 +27,7 @@
#include "linden_common.h"
#include "llallocator.h"
#if LL_USE_TCMALLOC
#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER)
#include "google/heap-profiler.h"
#include "google/commandlineflags_public.h"

View File

@ -69,6 +69,12 @@ ECursorType getCursorFromString(const std::string& cursor_string)
cursor_string_table["UI_CURSOR_TOOLSIT"] = UI_CURSOR_TOOLSIT;
cursor_string_table["UI_CURSOR_TOOLBUY"] = UI_CURSOR_TOOLBUY;
cursor_string_table["UI_CURSOR_TOOLOPEN"] = UI_CURSOR_TOOLOPEN;
cursor_string_table["UI_CURSOR_TOOLPATHFINDING"] = UI_CURSOR_TOOLPATHFINDING;
cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHSTART"] = UI_CURSOR_TOOLPATHFINDING_PATH_START;
cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHSTARTADD"] = UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD;
cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHEND"] = UI_CURSOR_TOOLPATHFINDING_PATH_END;
cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHENDADD"] = UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD;
cursor_string_table["UI_CURSOR_TOOLNO"] = UI_CURSOR_TOOLNO;
}
std::map<std::string,U32>::const_iterator iter = cursor_string_table.find(cursor_string);

View File

@ -65,6 +65,12 @@ enum ECursorType {
UI_CURSOR_TOOLSIT,
UI_CURSOR_TOOLBUY,
UI_CURSOR_TOOLOPEN,
UI_CURSOR_TOOLPATHFINDING,
UI_CURSOR_TOOLPATHFINDING_PATH_START,
UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD,
UI_CURSOR_TOOLPATHFINDING_PATH_END,
UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD,
UI_CURSOR_TOOLNO,
UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor)
};

View File

@ -534,7 +534,7 @@ namespace
}
void commonInit(const std::string& dir)
void commonInit(const std::string& dir, bool log_to_stderr = true)
{
LLError::Settings::reset();
@ -542,7 +542,8 @@ namespace
LLError::setFatalFunction(LLError::crashAndLoop);
LLError::setTimeFunction(LLError::utcTime);
if (shouldLogToStderr())
// log_to_stderr is only false in the unit and integration tests to keep builds quieter
if (log_to_stderr && shouldLogToStderr())
{
LLError::addRecorder(new RecordToStderr(stderrLogWantsTime()));
}
@ -580,9 +581,9 @@ namespace LLError
#endif
}
void initForApplication(const std::string& dir)
void initForApplication(const std::string& dir, bool log_to_stderr)
{
commonInit(dir);
commonInit(dir, log_to_stderr);
}
void setPrintLocation(bool print)

View File

@ -35,7 +35,7 @@
#include "stdtypes.h"
/* Error Logging Facility
/** Error Logging Facility
Information for most users:
@ -100,7 +100,6 @@
even release. Which means you can use them to help debug even when deployed
to a real grid.
*/
namespace LLError
{
enum ELevel
@ -143,9 +142,13 @@ namespace LLError
CallSite(ELevel, const char* file, int line,
const std::type_info& class_info, const char* function, const char* broadTag, const char* narrowTag, bool printOnce);
#ifdef LL_LIBRARY_INCLUDE
bool shouldLog();
#else // LL_LIBRARY_INCLUDE
bool shouldLog()
{ return mCached ? mShouldLog : Log::shouldLog(*this); }
// this member function needs to be in-line for efficiency
#endif // LL_LIBRARY_INCLUDE
void invalidate();

View File

@ -62,7 +62,7 @@ namespace LLError
// logs to stderr, syslog, and windows debug log
// the identity string is used for in the syslog
LL_COMMON_API void initForApplication(const std::string& dir);
LL_COMMON_API void initForApplication(const std::string& dir, bool log_to_stderr = true);
// resets all logging settings to defaults needed by applicaitons
// logs to stderr and windows debug log
// sets up log configuration from the file logcontrol.xml in dir

View File

@ -61,6 +61,18 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE;
LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker;
#endif
void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
{
#ifdef SHOW_ASSERT
// Redundant, place to set breakpoints.
if (ptr%alignment!=0)
{
llwarns << "alignment check failed" << llendl;
}
llassert(ptr%alignment==0);
#endif
}
//static
void LLMemory::initClass()
{

View File

@ -27,7 +27,6 @@
#define LLMEMORY_H
#include "llmemtype.h"
#if LL_DEBUG
inline void* ll_aligned_malloc( size_t size, int align )
{
void* mem = malloc( size + (align - 1) + sizeof(void*) );
@ -43,10 +42,11 @@ inline void ll_aligned_free( void* ptr )
free( ((void**)ptr)[-1] );
}
#if !LL_USE_TCMALLOC
inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
{
#if defined(LL_WINDOWS)
return _mm_malloc(size, 16);
return _aligned_malloc(size, 16);
#elif defined(LL_DARWIN)
return malloc(size); // default osx malloc is 16 byte aligned.
#else
@ -58,21 +58,38 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi
#endif
}
inline void* ll_aligned_realloc_16(void* ptr, size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
{
#if defined(LL_WINDOWS)
return _aligned_realloc(ptr, size, 16);
#elif defined(LL_DARWIN)
return realloc(ptr,size); // default osx malloc is 16 byte aligned.
#else
return realloc(ptr,size); // FIXME not guaranteed to be aligned.
#endif
}
inline void ll_aligned_free_16(void *p)
{
#if defined(LL_WINDOWS)
_mm_free(p);
_aligned_free(p);
#elif defined(LL_DARWIN)
return free(p);
#else
free(p); // posix_memalign() is compatible with heap deallocator
#endif
}
#else // USE_TCMALLOC
// ll_aligned_foo_16 are not needed with tcmalloc
#define ll_aligned_malloc_16 malloc
#define ll_aligned_realloc_16 realloc
#define ll_aligned_free_16 free
#endif // USE_TCMALLOC
inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
{
#if defined(LL_WINDOWS)
return _mm_malloc(size, 32);
return _aligned_malloc(size, 32);
#elif defined(LL_DARWIN)
return ll_aligned_malloc( size, 32 );
#else
@ -87,22 +104,13 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi
inline void ll_aligned_free_32(void *p)
{
#if defined(LL_WINDOWS)
_mm_free(p);
_aligned_free(p);
#elif defined(LL_DARWIN)
ll_aligned_free( p );
#else
free(p); // posix_memalign() is compatible with heap deallocator
#endif
}
#else // LL_DEBUG
// ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals)
#define ll_aligned_malloc( size, align ) malloc(size)
#define ll_aligned_free( ptr ) free(ptr)
#define ll_aligned_malloc_16 malloc
#define ll_aligned_free_16 free
#define ll_aligned_malloc_32 malloc
#define ll_aligned_free_32 free
#endif // LL_DEBUG
#ifndef __DEBUG_PRIVATE_MEM__
#define __DEBUG_PRIVATE_MEM__ 0
@ -512,4 +520,13 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr)
// LLSingleton moved to llsingleton.h
LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
#ifdef SHOW_ASSERT
#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
#else
#define ll_assert_aligned(ptr,alignment)
#endif
#endif

View File

@ -140,6 +140,10 @@ public:
}
protected:
#ifdef LL_LIBRARY_INCLUDE
void ref();
void unref();
#else
void ref()
{
if (mPointer)
@ -162,7 +166,7 @@ protected:
}
}
}
#endif
protected:
Type* mPointer;
};

View File

@ -55,6 +55,10 @@ static const char LEGACY_NON_HEADER[] = "<llsd>";
const std::string LLSD_BINARY_HEADER("LLSD/Binary");
const std::string LLSD_XML_HEADER("LLSD/XML");
//used to deflate a gzipped asset (currently used for navmeshes)
#define windowBits 15
#define ENABLE_ZLIB_GZIP 32
/**
* LLSDSerialize
*/
@ -2096,7 +2100,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
strm.next_in = in;
S32 ret = inflateInit(&strm);
do
{
strm.avail_out = CHUNK;
@ -2159,12 +2163,87 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
llwarns << "Failed to unzip LLSD block" << llendl;
free(result);
return false;
}
}
}
free(result);
return true;
}
//This unzip function will only work with a gzip header and trailer - while the contents
//of the actual compressed data is the same for either format (gzip vs zlib ), the headers
//and trailers are different for the formats.
U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size )
{
U8* result = NULL;
U32 cur_size = 0;
z_stream strm;
const U32 CHUNK = 0x4000;
U8 *in = new U8[size];
is.read((char*) in, size);
U8 out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = size;
strm.next_in = in;
S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP );
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR)
{
inflateEnd(&strm);
free(result);
delete [] in;
valid = false;
}
switch (ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
free(result);
delete [] in;
valid = false;
break;
}
U32 have = CHUNK-strm.avail_out;
result = (U8*) realloc(result, cur_size + have);
memcpy(result+cur_size, out, have);
cur_size += have;
} while (ret == Z_OK);
inflateEnd(&strm);
delete [] in;
if (ret != Z_STREAM_END)
{
free(result);
valid = false;
return NULL;
}
//result now points to the decompressed LLSD block
{
outsize= cur_size;
valid = true;
}
return result;
}

View File

@ -793,5 +793,5 @@ public:
//dirty little zip functions -- yell at davep
LL_COMMON_API std::string zip_llsd(LLSD& data);
LL_COMMON_API bool unzip_llsd(LLSD& data, std::istream& is, S32 size);
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
#endif // LL_LLSDSERIALIZE_H

View File

@ -28,41 +28,48 @@
enum
{
LL_SIM_STAT_TIME_DILATION, // 0
LL_SIM_STAT_FPS,
LL_SIM_STAT_PHYSFPS,
LL_SIM_STAT_AGENTUPS,
LL_SIM_STAT_FRAMEMS,
LL_SIM_STAT_NETMS, // 5
LL_SIM_STAT_SIMOTHERMS,
LL_SIM_STAT_SIMPHYSICSMS,
LL_SIM_STAT_AGENTMS,
LL_SIM_STAT_IMAGESMS,
LL_SIM_STAT_SCRIPTMS, // 10
LL_SIM_STAT_NUMTASKS,
LL_SIM_STAT_NUMTASKSACTIVE,
LL_SIM_STAT_NUMAGENTMAIN,
LL_SIM_STAT_NUMAGENTCHILD,
LL_SIM_STAT_NUMSCRIPTSACTIVE, // 15
LL_SIM_STAT_LSLIPS,
LL_SIM_STAT_INPPS,
LL_SIM_STAT_OUTPPS,
LL_SIM_STAT_PENDING_DOWNLOADS,
LL_SIM_STAT_PENDING_UPLOADS, // 20
LL_SIM_STAT_VIRTUAL_SIZE_KB,
LL_SIM_STAT_RESIDENT_SIZE_KB,
LL_SIM_STAT_PENDING_LOCAL_UPLOADS,
LL_SIM_STAT_TOTAL_UNACKED_BYTES,
LL_SIM_STAT_PHYSICS_PINNED_TASKS, // 25
LL_SIM_STAT_PHYSICS_LOD_TASKS,
LL_SIM_STAT_SIMPHYSICSSTEPMS,
LL_SIM_STAT_SIMPHYSICSSHAPEMS,
LL_SIM_STAT_SIMPHYSICSOTHERMS,
LL_SIM_STAT_SIMPHYSICSMEMORY, // 30
LL_SIM_STAT_SCRIPT_EPS,
LL_SIM_STAT_SIMSPARETIME,
LL_SIM_STAT_SIMSLEEPTIME,
LL_SIM_STAT_IOPUMPTIME,
LL_SIM_STAT_TIME_DILATION = 0,
LL_SIM_STAT_FPS = 1,
LL_SIM_STAT_PHYSFPS = 2,
LL_SIM_STAT_AGENTUPS = 3,
LL_SIM_STAT_FRAMEMS = 4,
LL_SIM_STAT_NETMS = 5,
LL_SIM_STAT_SIMOTHERMS = 6,
LL_SIM_STAT_SIMPHYSICSMS = 7,
LL_SIM_STAT_AGENTMS = 8,
LL_SIM_STAT_IMAGESMS = 9,
LL_SIM_STAT_SCRIPTMS = 10,
LL_SIM_STAT_NUMTASKS = 11,
LL_SIM_STAT_NUMTASKSACTIVE = 12,
LL_SIM_STAT_NUMAGENTMAIN = 13,
LL_SIM_STAT_NUMAGENTCHILD = 14,
LL_SIM_STAT_NUMSCRIPTSACTIVE = 15,
LL_SIM_STAT_LSLIPS = 16,
LL_SIM_STAT_INPPS = 17,
LL_SIM_STAT_OUTPPS = 18,
LL_SIM_STAT_PENDING_DOWNLOADS = 19,
LL_SIM_STAT_PENDING_UPLOADS = 20,
LL_SIM_STAT_VIRTUAL_SIZE_KB = 21,
LL_SIM_STAT_RESIDENT_SIZE_KB = 22,
LL_SIM_STAT_PENDING_LOCAL_UPLOADS = 23,
LL_SIM_STAT_TOTAL_UNACKED_BYTES = 24,
LL_SIM_STAT_PHYSICS_PINNED_TASKS = 25,
LL_SIM_STAT_PHYSICS_LOD_TASKS = 26,
LL_SIM_STAT_SIMPHYSICSSTEPMS = 27,
LL_SIM_STAT_SIMPHYSICSSHAPEMS = 28,
LL_SIM_STAT_SIMPHYSICSOTHERMS = 29,
LL_SIM_STAT_SIMPHYSICSMEMORY = 30,
LL_SIM_STAT_SCRIPT_EPS = 31,
LL_SIM_STAT_SIMSPARETIME = 32,
LL_SIM_STAT_SIMSLEEPTIME = 33,
LL_SIM_STAT_IOPUMPTIME = 34,
LL_SIM_STAT_PCTSCRIPTSRUN = 35,
LL_SIM_STAT_REGION_IDLE = 36, // dataserver only
LL_SIM_STAT_REGION_IDLE_POSSIBLE = 37, // dataserver only
LL_SIM_STAT_SIMAISTEPTIMEMS = 38,
LL_SIM_STAT_SKIPPEDAISILSTEPS_PS = 39,
LL_SIM_STAT_PCTSTEPPEDCHARACTERS = 40
};
#endif

View File

@ -183,6 +183,9 @@ public:
static bool isPunct(char a) { return ispunct((unsigned char)a) != 0; }
static bool isPunct(llwchar a) { return iswpunct(a) != 0; }
static bool isAlpha(char a) { return isalpha((unsigned char)a) != 0; }
static bool isAlpha(llwchar a) { return iswalpha(a) != 0; }
static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }

View File

@ -922,3 +922,174 @@ LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const
}
return result;
}
// Construct
LLUUID::LLUUID()
{
setNull();
}
// Faster than copying from memory
void LLUUID::setNull()
{
U32 *word = (U32 *)mData;
word[0] = 0;
word[1] = 0;
word[2] = 0;
word[3] = 0;
}
// Compare
bool LLUUID::operator==(const LLUUID& rhs) const
{
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
// Note: binary & to avoid branching
return
(tmp[0] == rhstmp[0]) &
(tmp[1] == rhstmp[1]) &
(tmp[2] == rhstmp[2]) &
(tmp[3] == rhstmp[3]);
}
bool LLUUID::operator!=(const LLUUID& rhs) const
{
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
// Note: binary | to avoid branching
return
(tmp[0] != rhstmp[0]) |
(tmp[1] != rhstmp[1]) |
(tmp[2] != rhstmp[2]) |
(tmp[3] != rhstmp[3]);
}
/*
// JC: This is dangerous. It allows UUIDs to be cast automatically
// to integers, among other things. Use isNull() or notNull().
LLUUID::operator bool() const
{
U32 *word = (U32 *)mData;
return (word[0] | word[1] | word[2] | word[3]) > 0;
}
*/
BOOL LLUUID::notNull() const
{
U32 *word = (U32 *)mData;
return (word[0] | word[1] | word[2] | word[3]) > 0;
}
// Faster than == LLUUID::null because doesn't require
// as much memory access.
BOOL LLUUID::isNull() const
{
U32 *word = (U32 *)mData;
// If all bits are zero, return !0 == TRUE
return !(word[0] | word[1] | word[2] | word[3]);
}
// Copy constructor
LLUUID::LLUUID(const LLUUID& rhs)
{
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
tmp[0] = rhstmp[0];
tmp[1] = rhstmp[1];
tmp[2] = rhstmp[2];
tmp[3] = rhstmp[3];
}
LLUUID::~LLUUID()
{
}
// Assignment
LLUUID& LLUUID::operator=(const LLUUID& rhs)
{
// No need to check the case where this==&rhs. The branch is slower than the write.
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
tmp[0] = rhstmp[0];
tmp[1] = rhstmp[1];
tmp[2] = rhstmp[2];
tmp[3] = rhstmp[3];
return *this;
}
LLUUID::LLUUID(const char *in_string)
{
if (!in_string || in_string[0] == 0)
{
setNull();
return;
}
set(in_string);
}
LLUUID::LLUUID(const std::string& in_string)
{
if (in_string.empty())
{
setNull();
return;
}
set(in_string);
}
// IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order
// IW: this will make me very sad
bool LLUUID::operator<(const LLUUID &rhs) const
{
U32 i;
for( i = 0; i < (UUID_BYTES - 1); i++ )
{
if( mData[i] != rhs.mData[i] )
{
return (mData[i] < rhs.mData[i]);
}
}
return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]);
}
bool LLUUID::operator>(const LLUUID &rhs) const
{
U32 i;
for( i = 0; i < (UUID_BYTES - 1); i++ )
{
if( mData[i] != rhs.mData[i] )
{
return (mData[i] > rhs.mData[i]);
}
}
return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]);
}
U16 LLUUID::getCRC16() const
{
// A UUID is 16 bytes, or 8 shorts.
U16 *short_data = (U16*)mData;
U16 out = 0;
out += short_data[0];
out += short_data[1];
out += short_data[2];
out += short_data[3];
out += short_data[4];
out += short_data[5];
out += short_data[6];
out += short_data[7];
return out;
}
U32 LLUUID::getCRC32() const
{
U32 *tmp = (U32*)mData;
return tmp[0] + tmp[1] + tmp[2] + tmp[3];
}

View File

@ -129,177 +129,6 @@ public:
typedef std::vector<LLUUID> uuid_vec_t;
// Construct
inline LLUUID::LLUUID()
{
setNull();
}
// Faster than copying from memory
inline void LLUUID::setNull()
{
U32 *word = (U32 *)mData;
word[0] = 0;
word[1] = 0;
word[2] = 0;
word[3] = 0;
}
// Compare
inline bool LLUUID::operator==(const LLUUID& rhs) const
{
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
// Note: binary & to avoid branching
return
(tmp[0] == rhstmp[0]) &
(tmp[1] == rhstmp[1]) &
(tmp[2] == rhstmp[2]) &
(tmp[3] == rhstmp[3]);
}
inline bool LLUUID::operator!=(const LLUUID& rhs) const
{
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
// Note: binary | to avoid branching
return
(tmp[0] != rhstmp[0]) |
(tmp[1] != rhstmp[1]) |
(tmp[2] != rhstmp[2]) |
(tmp[3] != rhstmp[3]);
}
/*
// JC: This is dangerous. It allows UUIDs to be cast automatically
// to integers, among other things. Use isNull() or notNull().
inline LLUUID::operator bool() const
{
U32 *word = (U32 *)mData;
return (word[0] | word[1] | word[2] | word[3]) > 0;
}
*/
inline BOOL LLUUID::notNull() const
{
U32 *word = (U32 *)mData;
return (word[0] | word[1] | word[2] | word[3]) > 0;
}
// Faster than == LLUUID::null because doesn't require
// as much memory access.
inline BOOL LLUUID::isNull() const
{
U32 *word = (U32 *)mData;
// If all bits are zero, return !0 == TRUE
return !(word[0] | word[1] | word[2] | word[3]);
}
// Copy constructor
inline LLUUID::LLUUID(const LLUUID& rhs)
{
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
tmp[0] = rhstmp[0];
tmp[1] = rhstmp[1];
tmp[2] = rhstmp[2];
tmp[3] = rhstmp[3];
}
inline LLUUID::~LLUUID()
{
}
// Assignment
inline LLUUID& LLUUID::operator=(const LLUUID& rhs)
{
// No need to check the case where this==&rhs. The branch is slower than the write.
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
tmp[0] = rhstmp[0];
tmp[1] = rhstmp[1];
tmp[2] = rhstmp[2];
tmp[3] = rhstmp[3];
return *this;
}
inline LLUUID::LLUUID(const char *in_string)
{
if (!in_string || in_string[0] == 0)
{
setNull();
return;
}
set(in_string);
}
inline LLUUID::LLUUID(const std::string& in_string)
{
if (in_string.empty())
{
setNull();
return;
}
set(in_string);
}
// IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order
// IW: this will make me very sad
inline bool LLUUID::operator<(const LLUUID &rhs) const
{
U32 i;
for( i = 0; i < (UUID_BYTES - 1); i++ )
{
if( mData[i] != rhs.mData[i] )
{
return (mData[i] < rhs.mData[i]);
}
}
return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]);
}
inline bool LLUUID::operator>(const LLUUID &rhs) const
{
U32 i;
for( i = 0; i < (UUID_BYTES - 1); i++ )
{
if( mData[i] != rhs.mData[i] )
{
return (mData[i] > rhs.mData[i]);
}
}
return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]);
}
inline U16 LLUUID::getCRC16() const
{
// A UUID is 16 bytes, or 8 shorts.
U16 *short_data = (U16*)mData;
U16 out = 0;
out += short_data[0];
out += short_data[1];
out += short_data[2];
out += short_data[3];
out += short_data[4];
out += short_data[5];
out += short_data[6];
out += short_data[7];
return out;
}
inline U32 LLUUID::getCRC32() const
{
U32 *tmp = (U32*)mData;
return tmp[0] + tmp[1] + tmp[2] + tmp[3];
}
// Helper structure for ordering lluuids in stl containers.
// eg: std::map<LLUUID, LLWidget*, lluuid_less> widget_map;
@ -329,3 +158,5 @@ public:
};
#endif

View File

@ -28,8 +28,8 @@
#define LL_LLVERSIONVIEWER_H
const S32 LL_VERSION_MAJOR = 3;
const S32 LL_VERSION_MINOR = 3;
const S32 LL_VERSION_PATCH = 3;
const S32 LL_VERSION_MINOR = 4;
const S32 LL_VERSION_PATCH = 1;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";

View File

@ -45,7 +45,7 @@ const S32 PARCEL_UNIT_AREA = 16;
const F32 PARCEL_HEIGHT = 50.f;
//Height above ground which parcel boundries exist for explicitly banned avatars
const F32 BAN_HEIGHT = 768.f;
const F32 BAN_HEIGHT = 5000.f;
// Maximum number of entries in an access list
const S32 PARCEL_MAX_ACCESS_LIST = 300;

View File

@ -117,6 +117,7 @@ if (LL_TESTS)
# INTEGRATION TESTS
set(test_libs llmath llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
# TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
LL_ADD_INTEGRATION_TEST(alignment "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llbbox llbbox.cpp "${test_libs}")
LL_ADD_INTEGRATION_TEST(llquaternion llquaternion.cpp "${test_libs}")
LL_ADD_INTEGRATION_TEST(mathmisc "" "${test_libs}")

View File

@ -60,7 +60,7 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
// roll(), pitch(), yaw()
// etc...
LL_ALIGN_PREFIX(16)
class LLCamera
: public LLCoordFrame
{
@ -108,7 +108,7 @@ public:
};
private:
LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
U8 mPlaneMask[8]; // 8 for alignment
F32 mView; // angle between top and bottom frustum planes in radians.
@ -116,13 +116,13 @@ private:
S32 mViewHeightInPixels; // for ViewHeightInPixels() only
F32 mNearPlane;
F32 mFarPlane;
LLPlane mLocalPlanes[4];
LL_ALIGN_16(LLPlane mLocalPlanes[4]);
F32 mFixedDistance; // Always return this distance, unless < 0
LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test
F32 mFrustRadiusSquared;
LLPlane mWorldPlanes[PLANE_NUM];
LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
LL_ALIGN_16(LLPlane mWorldPlanes[PLANE_NUM]);
LL_ALIGN_16(LLPlane mHorizPlanes[HORIZ_PLANE_NUM]);
U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
@ -208,7 +208,7 @@ protected:
void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
void calculateWorldFrustumPlanes();
};
} LL_ALIGN_POSTFIX(16);
#endif

View File

@ -85,7 +85,7 @@ const F32 F_ALMOST_ONE = 1.0f - F_ALMOST_ZERO;
const F32 FP_MAG_THRESHOLD = 0.0000001f;
// TODO: Replace with logic like is_approx_equal
inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
// These functions work by interpreting sign+exp+mantissa as an unsigned
// integer.
@ -111,13 +111,13 @@ inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f <
// WARNING: Infinity is comparable with F32_MAX and negative
// infinity is comparable with F32_MIN
inline BOOL is_approx_equal(F32 x, F32 y)
inline bool is_approx_equal(F32 x, F32 y)
{
const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
return (std::abs((S32) ((U32&)x - (U32&)y) ) < COMPARE_MANTISSA_UP_TO_BIT);
}
inline BOOL is_approx_equal(F64 x, F64 y)
inline bool is_approx_equal(F64 x, F64 y)
{
const S64 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT);

View File

@ -111,7 +111,7 @@ public:
protected:
LLVector4a mColumns[3];
LL_ALIGN_16(LLVector4a mColumns[3]);
};

View File

@ -34,7 +34,7 @@
class LLMatrix4a
{
public:
LLVector4a mMatrix[4];
LL_ALIGN_16(LLVector4a mMatrix[4]);
inline void clear()
{

View File

@ -89,7 +89,7 @@ public:
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeListener<T> oct_listener;
/*void* operator new(size_t size)
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
@ -97,7 +97,7 @@ public:
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}*/
}
LLOctreeNode( const LLVector4a& center,
const LLVector4a& size,

View File

@ -36,6 +36,8 @@
// The plane normal = [A, B, C]
// The closest approach = D / sqrt(A*A + B*B + C*C)
LL_ALIGN_PREFIX(16)
class LLPlane
{
public:
@ -94,7 +96,7 @@ public:
private:
LLVector4a mV;
};
} LL_ALIGN_POSTFIX(16);

View File

@ -67,11 +67,10 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
#include <xmmintrin.h>
#include <emmintrin.h>
#include "llmemory.h"
#include "llsimdtypes.h"
#include "llsimdtypes.inl"

View File

@ -62,6 +62,7 @@ inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b)
inline LLSimdScalar operator-(const LLSimdScalar& a)
{
static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
ll_assert_aligned(signMask,16);
return _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), a);
}
@ -146,6 +147,7 @@ inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs)
inline LLSimdScalar LLSimdScalar::getAbs() const
{
static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
ll_assert_aligned(F_ABS_MASK_4A,16);
return _mm_and_ps( mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));
}

View File

@ -24,6 +24,7 @@
* $/LicenseInfo$
*/
#include "llmemory.h"
#include "llmath.h"
#include "llquantize.h"
@ -44,7 +45,10 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F
assert(dst != NULL);
assert(bytes > 0);
assert((bytes % sizeof(F32))== 0);
ll_assert_aligned(src,16);
ll_assert_aligned(dst,16);
assert(bytes%16==0);
F32* end = dst + (bytes / sizeof(F32) );
if (bytes > 64)
@ -189,6 +193,8 @@ void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high )
LLVector4a oneOverDelta;
{
static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f };
ll_assert_aligned(F_TWO_4A,16);
LLVector4a two; two.load4a( F_TWO_4A );
// Here we use _mm_rcp_ps plus one round of newton-raphson

View File

@ -32,6 +32,7 @@ class LLRotation;
#include <assert.h>
#include "llpreprocessor.h"
#include "llmemory.h"
///////////////////////////////////
// FIRST TIME USERS PLEASE READ
@ -46,6 +47,7 @@ class LLRotation;
// LLVector3/LLVector4.
/////////////////////////////////
LL_ALIGN_PREFIX(16)
class LLVector4a
{
public:
@ -82,6 +84,7 @@ public:
}
// Copy words 16-byte blocks from src to dst. Source and destination must not overlap.
// Source and dest must be 16-byte aligned and size must be multiple of 16.
static void memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes);
////////////////////////////////////
@ -90,6 +93,7 @@ public:
LLVector4a()
{ //DO NOT INITIALIZE -- The overhead is completely unnecessary
ll_assert_aligned(this,16);
}
LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f)
@ -313,7 +317,7 @@ public:
private:
LLQuad mQ;
};
} LL_ALIGN_POSTFIX(16);
inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p)
{

View File

@ -475,6 +475,7 @@ inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F3
inline LLBool32 LLVector4a::isFinite3() const
{
static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 };
ll_assert_aligned(nanOrInfMask,16);
const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask);
const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV );
const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV ));

View File

@ -27,6 +27,7 @@
#ifndef LL_VECTOR4LOGICAL_H
#define LL_VECTOR4LOGICAL_H
#include "llmemory.h"
////////////////////////////
// LLVector4Logical
@ -77,6 +78,7 @@ public:
inline LLVector4Logical& invert()
{
static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
ll_assert_aligned(allOnes,16);
mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) );
return *this;
}

View File

@ -95,17 +95,6 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1;
extern BOOL gDebugGL;
void assert_aligned(void* ptr, uintptr_t alignment)
{
#if 0
uintptr_t t = (uintptr_t) ptr;
if (t%alignment != 0)
{
llerrs << "Alignment check failed." << llendl;
}
#endif
}
BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)
{
LLVector3 test = (pt2-pt1)%(pt3-pt2);
@ -6962,14 +6951,14 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
if (num_verts)
{
mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
assert_aligned(mPositions, 16);
ll_assert_aligned(mPositions, 16);
mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
assert_aligned(mNormals, 16);
ll_assert_aligned(mNormals, 16);
//pad texture coordinate block end to allow for QWORD reads
S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF;
mTexCoords = (LLVector2*) ll_aligned_malloc_16(size);
assert_aligned(mTexCoords, 16);
ll_assert_aligned(mTexCoords, 16);
}
else
{
@ -6993,14 +6982,17 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
// S32 old_size = mNumVertices*16;
//positions
mPositions = (LLVector4a*) realloc(mPositions, new_size);
mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size);
ll_assert_aligned(mPositions,16);
//normals
mNormals = (LLVector4a*) realloc(mNormals, new_size);
mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size);
ll_assert_aligned(mNormals,16);
//tex coords
new_size = ((new_verts*8)+0xF) & ~0xF;
mTexCoords = (LLVector2*) realloc(mTexCoords, new_size);
mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size);
ll_assert_aligned(mTexCoords,16);
//just clear binormals
@ -7053,7 +7045,8 @@ void LLVolumeFace::pushIndex(const U16& idx)
S32 old_size = ((mNumIndices*2)+0xF) & ~0xF;
if (new_size != old_size)
{
mIndices = (U16*) realloc(mIndices, new_size);
mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size);
ll_assert_aligned(mIndices,16);
}
mIndices[mNumIndices++] = idx;
@ -7094,12 +7087,12 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
}
//allocate new buffer space
mPositions = (LLVector4a*) realloc(mPositions, new_count*sizeof(LLVector4a));
assert_aligned(mPositions, 16);
mNormals = (LLVector4a*) realloc(mNormals, new_count*sizeof(LLVector4a));
assert_aligned(mNormals, 16);
mTexCoords = (LLVector2*) realloc(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF);
assert_aligned(mTexCoords, 16);
mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a));
ll_assert_aligned(mPositions, 16);
mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a));
ll_assert_aligned(mNormals, 16);
mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF);
ll_assert_aligned(mTexCoords, 16);
mNumVertices = new_count;
@ -7145,7 +7138,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
new_count = mNumIndices + face.mNumIndices;
//allocate new index buffer
mIndices = (U16*) realloc(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF);
mIndices = (U16*) ll_aligned_realloc_16(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF);
//get destination address into new index buffer
U16* dst_idx = mIndices+mNumIndices;

View File

@ -37,6 +37,16 @@
class LLVolumeTriangle : public LLRefCount
{
public:
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLVolumeTriangle()
{
mBinIndex = -1;
@ -58,7 +68,7 @@ public:
}
LLVector4a mPositionGroup;
LL_ALIGN_16(LLVector4a mPositionGroup);
const LLVector4a* mV[3];
U16 mIndex[3];
@ -80,6 +90,16 @@ class LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
{
public:
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node);
~LLVolumeOctreeListener();
@ -106,8 +126,8 @@ public:
public:
LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
LLVector4a mExtents[2]; // extents (min, max) of this node and all its children
LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
};
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle>

View File

@ -0,0 +1,128 @@
/**
* @file v3dmath_test.cpp
* @author Vir
* @date 2011-12
* @brief v3dmath test cases.
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
// Tests related to allocating objects with alignment constraints, particularly for SSE support.
#include "linden_common.h"
#include "../test/lltut.h"
#include "../llmath.h"
#include "../llsimdmath.h"
#include "../llvector4a.h"
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void *p)
{
ll_aligned_free_16(p);
}
namespace tut
{
#define is_aligned(ptr,alignment) ((reinterpret_cast<uintptr_t>(ptr))%(alignment)==0)
#define is_aligned_relative(ptr,base_ptr,alignment) ((reinterpret_cast<uintptr_t>(ptr)-reinterpret_cast<uintptr_t>(base_ptr))%(alignment)==0)
struct alignment_test {};
typedef test_group<alignment_test> alignment_test_t;
typedef alignment_test_t::object alignment_test_object_t;
tut::alignment_test_t tut_alignment_test("LLAlignment");
LL_ALIGN_PREFIX(16)
class MyVector4a
{
LLQuad mQ;
} LL_ALIGN_POSTFIX(16);
// Verify that aligned allocators perform as advertised.
template<> template<>
void alignment_test_object_t::test<1>()
{
# ifdef LL_DEBUG
skip("This test fails on Windows when compiled in debug mode.");
# endif
const int num_tests = 7;
void *align_ptr;
for (int i=0; i<num_tests; i++)
{
align_ptr = ll_aligned_malloc_16(sizeof(MyVector4a));
ensure("ll_aligned_malloc_16 failed", is_aligned(align_ptr,16));
align_ptr = ll_aligned_realloc_16(align_ptr,2*sizeof(MyVector4a));
ensure("ll_aligned_realloc_16 failed", is_aligned(align_ptr,16));
ll_aligned_free_16(align_ptr);
align_ptr = ll_aligned_malloc_32(sizeof(MyVector4a));
ensure("ll_aligned_malloc_32 failed", is_aligned(align_ptr,32));
ll_aligned_free_32(align_ptr);
}
}
// In-place allocation of objects and arrays.
template<> template<>
void alignment_test_object_t::test<2>()
{
MyVector4a vec1;
ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16));
MyVector4a veca[12];
ensure("LLAlignment veca unaligned", is_aligned(veca,16));
}
// Heap allocation of objects and arrays.
template<> template<>
void alignment_test_object_t::test<3>()
{
# ifdef LL_DEBUG
skip("This test fails on Windows when compiled in debug mode.");
# endif
const int ARR_SIZE = 7;
for(int i=0; i<ARR_SIZE; i++)
{
MyVector4a *vecp = new MyVector4a;
ensure("LLAlignment vecp unaligned", is_aligned(vecp,16));
delete vecp;
}
MyVector4a *veca = new MyVector4a[ARR_SIZE];
ensure("LLAligment veca base", is_aligned(veca,16));
for(int i=0; i<ARR_SIZE; i++)
{
std::cout << "veca[" << i << "]" << std::endl;
ensure("LLAlignment veca member unaligned", is_aligned(&veca[i],16));
}
}
}

View File

@ -289,6 +289,8 @@ LLIOPipe::EStatus LLURLRequest::handleError(
}
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST("URL Request");
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");
static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
// virtual
LLIOPipe::EStatus LLURLRequest::process_impl(
@ -358,7 +360,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
{
PUMP_DEBUG;
LLIOPipe::EStatus status = STATUS_BREAK;
static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
{
LLFastTimer t(FTM_URL_PERFORM);
if(!mDetail->mCurlRequest->wait())
@ -371,8 +372,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
{
CURLcode result;
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");
bool newmsg = false;
{
LLFastTimer t(FTM_PROCESS_URL_REQUEST_GET_RESULT);

View File

@ -943,7 +943,6 @@ char const* const _PREHASH_SysGPU = LLMessageStringTable::getInstance()->getStri
char const* const _PREHASH_AvatarInterestsReply = LLMessageStringTable::getInstance()->getString("AvatarInterestsReply");
char const* const _PREHASH_StartLure = LLMessageStringTable::getInstance()->getString("StartLure");
char const* const _PREHASH_SysRAM = LLMessageStringTable::getInstance()->getString("SysRAM");
char const* const _PREHASH_ObjectPosition = LLMessageStringTable::getInstance()->getString("ObjectPosition");
char const* const _PREHASH_SitPosition = LLMessageStringTable::getInstance()->getString("SitPosition");
char const* const _PREHASH_StartTime = LLMessageStringTable::getInstance()->getString("StartTime");
char const* const _PREHASH_BornOn = LLMessageStringTable::getInstance()->getString("BornOn");
@ -999,7 +998,6 @@ char const* const _PREHASH_SnapshotID = LLMessageStringTable::getInstance()->get
char const* const _PREHASH_Aspect = LLMessageStringTable::getInstance()->getString("Aspect");
char const* const _PREHASH_ParamSize = LLMessageStringTable::getInstance()->getString("ParamSize");
char const* const _PREHASH_VoteCast = LLMessageStringTable::getInstance()->getString("VoteCast");
char const* const _PREHASH_CastsShadows = LLMessageStringTable::getInstance()->getString("CastsShadows");
char const* const _PREHASH_EveryoneMask = LLMessageStringTable::getInstance()->getString("EveryoneMask");
char const* const _PREHASH_ObjectSpinUpdate = LLMessageStringTable::getInstance()->getString("ObjectSpinUpdate");
char const* const _PREHASH_MaturePublish = LLMessageStringTable::getInstance()->getString("MaturePublish");
@ -1048,7 +1046,6 @@ char const* const _PREHASH_SimIP = LLMessageStringTable::getInstance()->getStrin
char const* const _PREHASH_GodID = LLMessageStringTable::getInstance()->getString("GodID");
char const* const _PREHASH_TeleportMinPrice = LLMessageStringTable::getInstance()->getString("TeleportMinPrice");
char const* const _PREHASH_VoteItem = LLMessageStringTable::getInstance()->getString("VoteItem");
char const* const _PREHASH_ObjectRotation = LLMessageStringTable::getInstance()->getString("ObjectRotation");
char const* const _PREHASH_SitRotation = LLMessageStringTable::getInstance()->getString("SitRotation");
char const* const _PREHASH_SnapSelection = LLMessageStringTable::getInstance()->getString("SnapSelection");
char const* const _PREHASH_SoundTrigger = LLMessageStringTable::getInstance()->getString("SoundTrigger");

View File

@ -943,7 +943,6 @@ extern char const* const _PREHASH_SysGPU;
extern char const* const _PREHASH_AvatarInterestsReply;
extern char const* const _PREHASH_StartLure;
extern char const* const _PREHASH_SysRAM;
extern char const* const _PREHASH_ObjectPosition;
extern char const* const _PREHASH_SitPosition;
extern char const* const _PREHASH_StartTime;
extern char const* const _PREHASH_BornOn;
@ -999,7 +998,6 @@ extern char const* const _PREHASH_SnapshotID;
extern char const* const _PREHASH_Aspect;
extern char const* const _PREHASH_ParamSize;
extern char const* const _PREHASH_VoteCast;
extern char const* const _PREHASH_CastsShadows;
extern char const* const _PREHASH_EveryoneMask;
extern char const* const _PREHASH_ObjectSpinUpdate;
extern char const* const _PREHASH_MaturePublish;
@ -1048,7 +1046,6 @@ extern char const* const _PREHASH_SimIP;
extern char const* const _PREHASH_GodID;
extern char const* const _PREHASH_TeleportMinPrice;
extern char const* const _PREHASH_VoteItem;
extern char const* const _PREHASH_ObjectRotation;
extern char const* const _PREHASH_SitRotation;
extern char const* const _PREHASH_SnapSelection;
extern char const* const _PREHASH_SoundTrigger;

View File

@ -258,6 +258,7 @@ namespace tut
void HTTPClientTestObject::test<1>()
{
LLHTTPClient::get(local_server, newResult());
runThePump();
ensureStatusOK();
ensure("result object wasn't destroyed", mResultDeleted);

View File

@ -7,12 +7,14 @@ include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLXML)
include(LLPhysicsExtensions)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILT_DIR}/include/collada/1.4
)

View File

@ -1026,7 +1026,8 @@ void LLModel::setVolumeFaceData(
if (tc.get())
{
LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32));
U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF;
LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size);
}
else
{

View File

@ -28,43 +28,47 @@
#define LL_OBJECT_FLAGS_H
// downstream flags from sim->viewer
const U32 FLAGS_USE_PHYSICS = 0x00000001;
const U32 FLAGS_CREATE_SELECTED = 0x00000002;
const U32 FLAGS_OBJECT_MODIFY = 0x00000004;
const U32 FLAGS_OBJECT_COPY = 0x00000008;
const U32 FLAGS_OBJECT_ANY_OWNER = 0x00000010;
const U32 FLAGS_OBJECT_YOU_OWNER = 0x00000020;
const U32 FLAGS_SCRIPTED = 0x00000040;
const U32 FLAGS_HANDLE_TOUCH = 0x00000080;
const U32 FLAGS_OBJECT_MOVE = 0x00000100;
const U32 FLAGS_TAKES_MONEY = 0x00000200;
const U32 FLAGS_PHANTOM = 0x00000400;
const U32 FLAGS_INVENTORY_EMPTY = 0x00000800;
const U32 FLAGS_USE_PHYSICS = (1U << 0);
const U32 FLAGS_CREATE_SELECTED = (1U << 1);
const U32 FLAGS_OBJECT_MODIFY = (1U << 2);
const U32 FLAGS_OBJECT_COPY = (1U << 3);
const U32 FLAGS_OBJECT_ANY_OWNER = (1U << 4);
const U32 FLAGS_OBJECT_YOU_OWNER = (1U << 5);
const U32 FLAGS_SCRIPTED = (1U << 6);
const U32 FLAGS_HANDLE_TOUCH = (1U << 7);
const U32 FLAGS_OBJECT_MOVE = (1U << 8);
const U32 FLAGS_TAKES_MONEY = (1U << 9);
const U32 FLAGS_PHANTOM = (1U << 10);
const U32 FLAGS_INVENTORY_EMPTY = (1U << 11);
const U32 FLAGS_JOINT_HINGE = 0x00001000;
const U32 FLAGS_JOINT_P2P = 0x00002000;
const U32 FLAGS_JOINT_LP2P = 0x00004000;
// const U32 FLAGS_JOINT_WHEEL = 0x00008000;
const U32 FLAGS_INCLUDE_IN_SEARCH = 0x00008000;
const U32 FLAGS_AFFECTS_NAVMESH = (1U << 12);
const U32 FLAGS_CHARACTER = (1U << 13);
const U32 FLAGS_VOLUME_DETECT = (1U << 14);
const U32 FLAGS_INCLUDE_IN_SEARCH = (1U << 15);
const U32 FLAGS_ALLOW_INVENTORY_DROP = 0x00010000;
const U32 FLAGS_OBJECT_TRANSFER = 0x00020000;
const U32 FLAGS_OBJECT_GROUP_OWNED = 0x00040000;
//const U32 FLAGS_OBJECT_YOU_OFFICER = 0x00080000;
const U32 FLAGS_ALLOW_INVENTORY_DROP = (1U << 16);
const U32 FLAGS_OBJECT_TRANSFER = (1U << 17);
const U32 FLAGS_OBJECT_GROUP_OWNED = (1U << 18);
//const U32 FLAGS_UNUSED_000 = (1U << 19); // was FLAGS_OBJECT_YOU_OFFICER
const U32 FLAGS_CAMERA_DECOUPLED = 0x00100000;
const U32 FLAGS_ANIM_SOURCE = 0x00200000;
const U32 FLAGS_CAMERA_SOURCE = 0x00400000;
const U32 FLAGS_CAMERA_DECOUPLED = (1U << 20);
const U32 FLAGS_ANIM_SOURCE = (1U << 21);
const U32 FLAGS_CAMERA_SOURCE = (1U << 22);
const U32 FLAGS_CAST_SHADOWS = 0x00800000;
//const U32 FLAGS_UNUSED_001 = (1U << 23); // was FLAGS_CAST_SHADOWS
const U32 FLAGS_OBJECT_OWNER_MODIFY = 0x10000000;
//const U32 FLAGS_UNUSED_002 = (1U << 24);
//const U32 FLAGS_UNUSED_003 = (1U << 25);
//const U32 FLAGS_UNUSED_004 = (1U << 26);
//const U32 FLAGS_UNUSED_005 = (1U << 27);
const U32 FLAGS_TEMPORARY_ON_REZ = 0x20000000;
const U32 FLAGS_TEMPORARY = 0x40000000;
const U32 FLAGS_ZLIB_COMPRESSED = 0x80000000;
const U32 FLAGS_OBJECT_OWNER_MODIFY = (1U << 28);
const U32 FLAGS_LOCAL = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE;
const U32 FLAGS_TEMPORARY_ON_REZ = (1U << 29);
//const U32 FLAGS_UNUSED_006 = (1U << 30); // was FLAGS_TEMPORARY
//const U32 FLAGS_UNUSED_007 = (1U << 31); // was FLAGS_ZLIB_COMPRESSED
const U32 FLAGS_LOCAL = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE;
typedef enum e_havok_joint_type
{
@ -77,4 +81,3 @@ typedef enum e_havok_joint_type
} EHavokJointType;
#endif

View File

@ -36,6 +36,7 @@ set(llrender_SOURCE_FILES
llglslshader.cpp
llimagegl.cpp
llpostprocess.cpp
llrendernavprim.cpp
llrendersphere.cpp
llshadermgr.cpp
lltexture.cpp
@ -59,6 +60,7 @@ set(llrender_HEADER_FILES
llimagegl.h
llpostprocess.h
llrender.h
llrendernavprim.h
llrendersphere.h
llshadermgr.h
lltexture.h

View File

@ -422,6 +422,16 @@ S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y
}
// font metrics - override for LLFontFreetype that returns units of virtual pixels
F32 LLFontGL::getAscenderHeight() const
{
return mFontFreetype->getAscenderHeight() / sScaleY;
}
F32 LLFontGL::getDescenderHeight() const
{
return mFontFreetype->getDescenderHeight() / sScaleY;
}
S32 LLFontGL::getLineHeight() const
{
return llceil(mFontFreetype->getAscenderHeight() / sScaleY) + llceil(mFontFreetype->getDescenderHeight() / sScaleY);

View File

@ -115,6 +115,8 @@ public:
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
// font metrics - override for LLFontFreetype that returns units of virtual pixels
F32 getAscenderHeight() const;
F32 getDescenderHeight() const;
S32 getLineHeight() const;
S32 getWidth(const std::string& utf8text) const;

View File

@ -0,0 +1,59 @@
/**
* @file llrendernavprim.cpp
* @brief Implementation of llrendernavprim
* @author Prep@lindenlab.com
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012, 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 "llrendernavprim.h"
#include "llrender.h"
#include "llvertexbuffer.h"
#include "v4coloru.h"
#include "v3math.h"
//=============================================================================
LLRenderNavPrim gRenderNav;
//=============================================================================
void LLRenderNavPrim::renderLLTri( const LLVector3& a, const LLVector3& b, const LLVector3& c, const LLColor4U& color ) const
{
LLColor4 cV(color);
gGL.color4fv( cV.mV );
gGL.begin(LLRender::TRIANGLES);
{
gGL.vertex3fv( a.mV );
gGL.vertex3fv( b.mV );
gGL.vertex3fv( c.mV );
}
gGL.end();
}
//=============================================================================
void LLRenderNavPrim::renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt )
{
pVBO->setBuffer( LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL );
pVBO->drawArrays( mode, 0, vertCnt );
}
//=============================================================================

View File

@ -0,0 +1,49 @@
/**
* @file llrendernavprim.h
* @brief Header file for llrendernavprim
* @author Prep@lindenlab.com
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012, 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_LLRENDERNAVPRIM_H
#define LL_LLRENDERNAVPRIM_H
#include "stdtypes.h"
class LLColor4U;
class LLVector3;
class LLVertexBuffer;
class LLRenderNavPrim
{
public:
//Draw simple tri
void renderLLTri( const LLVector3& a, const LLVector3& b, const LLVector3& c, const LLColor4U& color ) const;
//Draw the contents of vertex buffer
void renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt );
private:
};
extern LLRenderNavPrim gRenderNav;
#endif // LL_LLRENDERNAVPRIM_H

View File

@ -290,6 +290,8 @@ void LLVBOPool::seedPool()
}
void LLVBOPool::cleanup()
{
U32 size = LL_VBO_BLOCK_SIZE;

View File

@ -23,6 +23,7 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LIBS_PREBUILD_DIR}/include/hunspell
)
set(llui_SOURCE_FILES
@ -84,6 +85,7 @@ set(llui_SOURCE_FILES
llsearcheditor.cpp
llslider.cpp
llsliderctrl.cpp
llspellcheck.cpp
llspinctrl.cpp
llstatbar.cpp
llstatgraph.cpp
@ -191,6 +193,8 @@ set(llui_HEADER_FILES
llscrolllistitem.h
llsliderctrl.h
llslider.h
llspellcheck.h
llspellcheckmenuhandler.h
llspinctrl.h
llstatbar.h
llstatgraph.h
@ -260,6 +264,7 @@ target_link_libraries(llui
${LLXUIXML_LIBRARIES}
${LLXML_LIBRARIES}
${LLMATH_LIBRARIES}
${HUNSPELL_LIBRARY}
${LLCOMMON_LIBRARIES} # must be after llimage, llwindow, llrender
)

View File

@ -45,6 +45,7 @@
#include "llkeyboard.h"
#include "llrect.h"
#include "llresmgr.h"
#include "llspellcheck.h"
#include "llstring.h"
#include "llwindow.h"
#include "llui.h"
@ -65,6 +66,7 @@ const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing
const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing
const F32 AUTO_SCROLL_TIME = 0.05f;
const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval?
const F32 SPELLCHECK_DELAY = 0.5f; // delay between the last keypress and spell checking the word the cursor is on
const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET
@ -88,6 +90,7 @@ LLLineEditor::Params::Params()
background_image_focused("background_image_focused"),
select_on_focus("select_on_focus", false),
revert_on_esc("revert_on_esc", true),
spellcheck("spellcheck", false),
commit_on_focus_lost("commit_on_focus_lost", true),
ignore_tab("ignore_tab", true),
is_password("is_password", false),
@ -134,6 +137,9 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mIgnoreArrowKeys( FALSE ),
mIgnoreTab( p.ignore_tab ),
mDrawAsterixes( p.is_password ),
mSpellCheck( p.spellcheck ),
mSpellCheckStart(-1),
mSpellCheckEnd(-1),
mSelectAllonFocusReceived( p.select_on_focus ),
mSelectAllonCommit( TRUE ),
mPassDelete(FALSE),
@ -151,7 +157,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mHighlightColor(p.highlight_color()),
mPreeditBgColor(p.preedit_bg_color()),
mGLFont(p.font),
mContextMenuHandle()
mContextMenuHandle(),
mAutoreplaceCallback()
{
llassert( mMaxLengthBytes > 0 );
@ -177,6 +184,12 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
updateTextPadding();
setCursor(mText.length());
if (mSpellCheck)
{
LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLLineEditor::onSpellCheckSettingsChange, this));
}
mSpellCheckTimer.reset();
setPrevalidateInput(p.prevalidate_input_callback());
setPrevalidate(p.prevalidate_callback());
@ -195,7 +208,6 @@ LLLineEditor::~LLLineEditor()
gFocusMgr.releaseFocusIfNeeded( this );
}
void LLLineEditor::onFocusReceived()
{
gEditMenuHandler = this;
@ -519,6 +531,99 @@ void LLLineEditor::selectAll()
updatePrimary();
}
bool LLLineEditor::getSpellCheck() const
{
return (LLSpellChecker::getUseSpellCheck()) && (!mReadOnly) && (mSpellCheck);
}
const std::string& LLLineEditor::getSuggestion(U32 index) const
{
return (index < mSuggestionList.size()) ? mSuggestionList[index] : LLStringUtil::null;
}
U32 LLLineEditor::getSuggestionCount() const
{
return mSuggestionList.size();
}
void LLLineEditor::replaceWithSuggestion(U32 index)
{
for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
{
if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
{
deselect();
// Delete the misspelled word
mText.erase(it->first, it->second - it->first);
// Insert the suggestion in its place
LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
mText.insert(it->first, suggestion);
setCursor(it->first + (S32)suggestion.length());
break;
}
}
mSpellCheckStart = mSpellCheckEnd = -1;
}
void LLLineEditor::addToDictionary()
{
if (canAddToDictionary())
{
LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos));
}
}
bool LLLineEditor::canAddToDictionary() const
{
return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
}
void LLLineEditor::addToIgnore()
{
if (canAddToIgnore())
{
LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos));
}
}
bool LLLineEditor::canAddToIgnore() const
{
return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
}
std::string LLLineEditor::getMisspelledWord(U32 pos) const
{
for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
{
if ( (it->first <= pos) && (it->second >= pos) )
{
return wstring_to_utf8str(mText.getWString().substr(it->first, it->second - it->first));
}
}
return LLStringUtil::null;
}
bool LLLineEditor::isMisspelledWord(U32 pos) const
{
for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
{
if ( (it->first <= pos) && (it->second >= pos) )
{
return true;
}
}
return false;
}
void LLLineEditor::onSpellCheckSettingsChange()
{
// Recheck the spelling on every change
mMisspellRanges.clear();
mSpellCheckStart = mSpellCheckEnd = -1;
}
BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
{
@ -866,6 +971,12 @@ void LLLineEditor::addChar(const llwchar uni_char)
LLUI::reportBadKeystroke();
}
if (!mReadOnly && mAutoreplaceCallback != NULL)
{
// call callback
mAutoreplaceCallback(mText, mCursorPos);
}
getWindow()->hideCursorUntilMouseMove();
}
@ -1058,9 +1169,8 @@ void LLLineEditor::cut()
LLUI::reportBadKeystroke();
}
else
if( mKeystrokeCallback )
{
mKeystrokeCallback( this );
onKeystroke();
}
}
}
@ -1187,9 +1297,8 @@ void LLLineEditor::pasteHelper(bool is_primary)
LLUI::reportBadKeystroke();
}
else
if( mKeystrokeCallback )
{
mKeystrokeCallback( this );
onKeystroke();
}
}
}
@ -1442,9 +1551,10 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
// Notify owner if requested
if (!need_to_rollback && handled)
{
if (mKeystrokeCallback)
onKeystroke();
if ( (!selection_modified) && (KEY_BACKSPACE == key) )
{
mKeystrokeCallback(this);
mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
}
}
@ -1497,12 +1607,11 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
// Notify owner if requested
if( !need_to_rollback && handled )
{
if( mKeystrokeCallback )
{
// HACK! The only usage of this callback doesn't do anything with the character.
// We'll have to do something about this if something ever changes! - Doug
mKeystrokeCallback( this );
}
// HACK! The only usage of this callback doesn't do anything with the character.
// We'll have to do something about this if something ever changes! - Doug
onKeystroke();
mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
}
return handled;
@ -1531,9 +1640,7 @@ void LLLineEditor::doDelete()
if (!prevalidateInput(text_to_delete))
{
if( mKeystrokeCallback )
mKeystrokeCallback( this );
onKeystroke();
return;
}
setCursor(getCursor() + 1);
@ -1549,10 +1656,9 @@ void LLLineEditor::doDelete()
}
else
{
if( mKeystrokeCallback )
{
mKeystrokeCallback( this );
}
onKeystroke();
mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
}
}
@ -1624,6 +1730,10 @@ void LLLineEditor::draw()
background.stretch( -mBorderThickness );
S32 lineeditor_v_pad = (background.getHeight() - mGLFont->getLineHeight()) / 2;
if (mSpellCheck)
{
lineeditor_v_pad += 1;
}
drawBackground();
@ -1698,14 +1808,14 @@ void LLLineEditor::draw()
{
S32 select_left;
S32 select_right;
if( mSelectionStart < getCursor() )
if (mSelectionStart < mSelectionEnd)
{
select_left = mSelectionStart;
select_right = getCursor();
select_right = mSelectionEnd;
}
else
{
select_left = getCursor();
select_left = mSelectionEnd;
select_right = mSelectionStart;
}
@ -1749,7 +1859,7 @@ void LLLineEditor::draw()
if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) )
{
// unselected, right side
mGLFont->render(
rendered_text += mGLFont->render(
mText, mScrollHPos + rendered_text,
rendered_pixels_right, text_bottom,
text_color,
@ -1763,7 +1873,7 @@ void LLLineEditor::draw()
}
else
{
mGLFont->render(
rendered_text = mGLFont->render(
mText, mScrollHPos,
rendered_pixels_right, text_bottom,
text_color,
@ -1778,6 +1888,101 @@ void LLLineEditor::draw()
mBorder->setVisible(FALSE); // no more programmatic art.
#endif
if ( (getSpellCheck()) && (mText.length() > 2) )
{
// Calculate start and end indices for the first and last visible word
U32 start = prevWordPos(mScrollHPos), end = nextWordPos(mScrollHPos + rendered_text);
if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
{
const LLWString& text = mText.getWString().substr(start, end);
// Find the start of the first word
U32 word_start = 0, word_end = 0;
while ( (word_start < text.length()) && (!LLStringOps::isAlpha(text[word_start])) )
{
word_start++;
}
// Iterate over all words in the text block and check them one by one
mMisspellRanges.clear();
while (word_start < text.length())
{
// Find the end of the current word (special case handling for "'" when it's used as a contraction)
word_end = word_start + 1;
while ( (word_end < text.length()) &&
((LLWStringUtil::isPartOfWord(text[word_end])) ||
((L'\'' == text[word_end]) && (word_end + 1 < text.length()) &&
(LLStringOps::isAlnum(text[word_end - 1])) && (LLStringOps::isAlnum(text[word_end + 1])))) )
{
word_end++;
}
if (word_end > text.length())
{
break;
}
// Don't process words shorter than 3 characters
std::string word = wstring_to_utf8str(text.substr(word_start, word_end - word_start));
if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
{
mMisspellRanges.push_back(std::pair<U32, U32>(start + word_start, start + word_end));
}
// Find the start of the next word
word_start = word_end + 1;
while ( (word_start < text.length()) && (!LLWStringUtil::isPartOfWord(text[word_start])) )
{
word_start++;
}
}
mSpellCheckStart = start;
mSpellCheckEnd = end;
}
// Draw squiggly lines under any (visible) misspelled words
for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
{
// Skip over words that aren't (partially) visible
if ( ((it->first < start) && (it->second < start)) || (it->first > end) )
{
continue;
}
// Skip the current word if the user is still busy editing it
if ( (!mSpellCheckTimer.hasExpired()) && (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
{
continue;
}
S32 pxWidth = getRect().getWidth();
S32 pxStart = findPixelNearestPos(it->first - getCursor());
if (pxStart > pxWidth)
{
continue;
}
S32 pxEnd = findPixelNearestPos(it->second - getCursor());
if (pxEnd > pxWidth)
{
pxEnd = pxWidth;
}
S32 pxBottom = (S32)(text_bottom + mGLFont->getDescenderHeight());
gGL.color4ub(255, 0, 0, 200);
while (pxStart + 1 < pxEnd)
{
gl_line_2d(pxStart, pxBottom, pxStart + 2, pxBottom - 2);
if (pxStart + 3 < pxEnd)
{
gl_line_2d(pxStart + 2, pxBottom - 3, pxStart + 4, pxBottom - 1);
}
pxStart += 4;
}
}
}
// If we're editing...
if( hasFocus())
{
@ -2109,6 +2314,15 @@ void LLLineEditor::setSelectAllonFocusReceived(BOOL b)
mSelectAllonFocusReceived = b;
}
void LLLineEditor::onKeystroke()
{
if (mKeystrokeCallback)
{
mKeystrokeCallback(this);
}
mSpellCheckStart = mSpellCheckEnd = -1;
}
void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data)
{
@ -2231,10 +2445,9 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string,
// Update of the preedit should be caused by some key strokes.
mKeystrokeTimer.reset();
if( mKeystrokeCallback )
{
mKeystrokeCallback( this );
}
onKeystroke();
mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@ -2386,7 +2599,38 @@ void LLLineEditor::showContextMenu(S32 x, S32 y)
S32 screen_x, screen_y;
localPointToScreen(x, y, &screen_x, &screen_y);
menu->show(screen_x, screen_y);
setCursorAtLocalPos(x);
if (hasSelection())
{
if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) )
{
deselect();
}
else
{
setCursor(llmax(mSelectionStart, mSelectionEnd));
}
}
bool use_spellcheck = getSpellCheck(), is_misspelled = false;
if (use_spellcheck)
{
mSuggestionList.clear();
// If the cursor is on a misspelled word, retrieve suggestions for it
std::string misspelled_word = getMisspelledWord(mCursorPos);
if ((is_misspelled = !misspelled_word.empty()) == true)
{
LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList);
}
}
menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
menu->show(screen_x, screen_y, this);
}
}

View File

@ -40,6 +40,7 @@
#include "llframetimer.h"
#include "lleditmenuhandler.h"
#include "llspellcheckmenuhandler.h"
#include "lluictrl.h"
#include "lluiimage.h"
#include "lluistring.h"
@ -54,7 +55,7 @@ class LLButton;
class LLContextMenu;
class LLLineEditor
: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor
: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor, public LLSpellCheckMenuHandler
{
public:
@ -86,6 +87,7 @@ public:
Optional<bool> select_on_focus,
revert_on_esc,
spellcheck,
commit_on_focus_lost,
ignore_tab,
is_password;
@ -146,6 +148,24 @@ public:
virtual void deselect();
virtual BOOL canDeselect() const;
// LLSpellCheckMenuHandler overrides
/*virtual*/ bool getSpellCheck() const;
/*virtual*/ const std::string& getSuggestion(U32 index) const;
/*virtual*/ U32 getSuggestionCount() const;
/*virtual*/ void replaceWithSuggestion(U32 index);
/*virtual*/ void addToDictionary();
/*virtual*/ bool canAddToDictionary() const;
/*virtual*/ void addToIgnore();
/*virtual*/ bool canAddToIgnore() const;
// Spell checking helper functions
std::string getMisspelledWord(U32 pos) const;
bool isMisspelledWord(U32 pos) const;
void onSpellCheckSettingsChange();
// view overrides
virtual void draw();
virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE);
@ -169,6 +189,9 @@ public:
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
typedef boost::function<void(LLUIString&, S32&)> autoreplace_callback_t;
autoreplace_callback_t mAutoreplaceCallback;
void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
const std::string& getLabel() { return mLabel.getString(); }
@ -223,6 +246,7 @@ public:
void setSelectAllonFocusReceived(BOOL b);
void setSelectAllonCommit(BOOL b) { mSelectAllonCommit = b; }
void onKeystroke();
typedef boost::function<void (LLLineEditor* caller, void* user_data)> callback_t;
void setKeystrokeCallback(callback_t callback, void* user_data);
@ -322,6 +346,13 @@ protected:
S32 mLastSelectionStart;
S32 mLastSelectionEnd;
bool mSpellCheck;
S32 mSpellCheckStart;
S32 mSpellCheckEnd;
LLTimer mSpellCheckTimer;
std::list<std::pair<U32, U32> > mMisspellRanges;
std::vector<std::string> mSuggestionList;
LLTextValidate::validate_func_t mPrevalidateFunc;
LLTextValidate::validate_func_t mPrevalidateInputFunc;

View File

@ -3854,7 +3854,7 @@ void LLContextMenu::setVisible(BOOL visible)
}
// Takes cursor position in screen space?
void LLContextMenu::show(S32 x, S32 y)
void LLContextMenu::show(S32 x, S32 y, LLView* spawning_view)
{
if (getChildList()->empty())
{
@ -3908,6 +3908,14 @@ void LLContextMenu::show(S32 x, S32 y)
setRect(rect);
arrange();
if (spawning_view)
{
mSpawningViewHandle = spawning_view->getHandle();
}
else
{
mSpawningViewHandle.markDead();
}
LLView::setVisible(TRUE);
}

View File

@ -670,7 +670,7 @@ public:
virtual void draw ();
virtual void show (S32 x, S32 y);
virtual void show (S32 x, S32 y, LLView* spawning_view = NULL);
virtual void hide ();
virtual BOOL handleHover ( S32 x, S32 y, MASK mask );
@ -683,10 +683,14 @@ public:
LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
LLView* getSpawningView() const { return mSpawningViewHandle.get(); }
void setSpawningView(LLHandle<LLView> spawning_view) { mSpawningViewHandle = spawning_view; }
protected:
BOOL mHoveredAnyItem;
LLMenuItemGL* mHoverItem;
LLRootHandle<LLContextMenu> mHandle;
LLHandle<LLView> mSpawningViewHandle;
};

View File

@ -1488,6 +1488,10 @@ bool LLNotifications::loadTemplates()
{
replaceFormText(notification.form_ref.form, "$canceltext", notification.form_ref.form_template.cancel_text);
}
if(notification.form_ref.form_template.help_text.isProvided())
{
replaceFormText(notification.form_ref.form, "$helptext", notification.form_ref.form_template.help_text);
}
if(notification.form_ref.form_template.ignore_text.isProvided())
{
replaceFormText(notification.form_ref.form, "$ignoretext", notification.form_ref.form_template.ignore_text);

View File

@ -121,6 +121,7 @@ struct LLNotificationTemplate
Optional<std::string> yes_text,
no_text,
cancel_text,
help_text,
ignore_text;
TemplateRef()
@ -128,6 +129,7 @@ struct LLNotificationTemplate
yes_text("yestext"),
no_text("notext"),
cancel_text("canceltext"),
help_text("helptext"),
ignore_text("ignoretext")
{}
};

View File

@ -389,12 +389,11 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
{
*show_h_scrollbar = TRUE;
*visible_height -= scrollbar_size;
// Note: Do *not* recompute *show_v_scrollbar here because with
// The view inside the scroll container should not be extended
// to container's full height to ensure the correct computation
// of *show_v_scrollbar after subtracting horizontal scrollbar_size.
// Must retest now that visible_height has changed
if( !*show_v_scrollbar && ((doc_height - *visible_height) > 1) )
{
*show_v_scrollbar = TRUE;

View File

@ -389,6 +389,22 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
return ret;
}
S32 LLScrollListCtrl::getNumSelected() const
{
S32 numSelected = 0;
for(item_list::const_iterator iter = mItemList.begin(); iter != mItemList.end(); ++iter)
{
LLScrollListItem* item = *iter;
if (item->getSelected())
{
++numSelected;
}
}
return numSelected;
}
S32 LLScrollListCtrl::getFirstSelectedIndex() const
{
S32 CurSelectedIndex = 0;

View File

@ -257,6 +257,7 @@ public:
LLScrollListItem* getFirstSelected() const;
virtual S32 getFirstSelectedIndex() const;
std::vector<LLScrollListItem*> getAllSelected() const;
S32 getNumSelected() const;
LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
// iterate over all items

505
indra/llui/llspellcheck.cpp Normal file
View File

@ -0,0 +1,505 @@
/**
* @file llspellcheck.cpp
* @brief Spell checking functionality
*
* $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$
*/
#include "linden_common.h"
#include "lldir.h"
#include "llsdserialize.h"
#include "llspellcheck.h"
#if LL_WINDOWS
#include <hunspell/hunspelldll.h>
#pragma comment(lib, "libhunspell.lib")
#else
#include <hunspell/hunspell.hxx>
#endif
static const std::string DICT_DIR = "dictionaries";
static const std::string DICT_FILE_CUSTOM = "user_custom.dic";
static const std::string DICT_FILE_IGNORE = "user_ignore.dic";
static const std::string DICT_FILE_MAIN = "dictionaries.xml";
static const std::string DICT_FILE_USER = "user_dictionaries.xml";
LLSD LLSpellChecker::sDictMap;
LLSpellChecker::settings_change_signal_t LLSpellChecker::sSettingsChangeSignal;
LLSpellChecker::LLSpellChecker()
: mHunspell(NULL)
{
// Load initial dictionary information
refreshDictionaryMap();
}
LLSpellChecker::~LLSpellChecker()
{
delete mHunspell;
}
bool LLSpellChecker::checkSpelling(const std::string& word) const
{
if ( (!mHunspell) || (word.length() < 3) || (0 != mHunspell->spell(word.c_str())) )
{
return true;
}
if (mIgnoreList.size() > 0)
{
std::string word_lower(word);
LLStringUtil::toLower(word_lower);
return (mIgnoreList.end() != std::find(mIgnoreList.begin(), mIgnoreList.end(), word_lower));
}
return false;
}
S32 LLSpellChecker::getSuggestions(const std::string& word, std::vector<std::string>& suggestions) const
{
suggestions.clear();
if ( (!mHunspell) || (word.length() < 3) )
{
return 0;
}
char** suggestion_list; int suggestion_cnt = 0;
if ( (suggestion_cnt = mHunspell->suggest(&suggestion_list, word.c_str())) != 0 )
{
for (int suggestion_index = 0; suggestion_index < suggestion_cnt; suggestion_index++)
{
suggestions.push_back(suggestion_list[suggestion_index]);
}
mHunspell->free_list(&suggestion_list, suggestion_cnt);
}
return suggestions.size();
}
// static
const LLSD LLSpellChecker::getDictionaryData(const std::string& dict_language)
{
for (LLSD::array_const_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
{
const LLSD& dict_entry = *it;
if (dict_language == dict_entry["language"].asString())
{
return dict_entry;
}
}
return LLSD();
}
// static
bool LLSpellChecker::hasDictionary(const std::string& dict_language, bool check_installed)
{
const LLSD dict_info = getDictionaryData(dict_language);
return dict_info.has("language") && ( (!check_installed) || (dict_info["installed"].asBoolean()) );
}
// static
void LLSpellChecker::setDictionaryData(const LLSD& dict_info)
{
const std::string dict_language = dict_info["language"].asString();
if (dict_language.empty())
{
return;
}
for (LLSD::array_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
{
LLSD& dict_entry = *it;
if (dict_language == dict_entry["language"].asString())
{
dict_entry = dict_info;
return;
}
}
sDictMap.append(dict_info);
return;
}
// static
void LLSpellChecker::refreshDictionaryMap()
{
const std::string app_path = getDictionaryAppPath();
const std::string user_path = getDictionaryUserPath();
// Load dictionary information (file name, friendly name, ...)
llifstream user_file(user_path + DICT_FILE_MAIN, std::ios::binary);
if ( (!user_file.is_open()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, user_file)) || (0 == sDictMap.size()) )
{
llifstream app_file(app_path + DICT_FILE_MAIN, std::ios::binary);
if ( (!app_file.is_open()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, app_file)) || (0 == sDictMap.size()) )
{
return;
}
}
// Load user installed dictionary information
llifstream custom_file(user_path + DICT_FILE_USER, std::ios::binary);
if (custom_file.is_open())
{
LLSD custom_dict_map;
LLSDSerialize::fromXMLDocument(custom_dict_map, custom_file);
for (LLSD::array_iterator it = custom_dict_map.beginArray(); it != custom_dict_map.endArray(); ++it)
{
LLSD& dict_info = *it;
dict_info["user_installed"] = true;
setDictionaryData(dict_info);
}
custom_file.close();
}
// Look for installed dictionaries
std::string tmp_app_path, tmp_user_path;
for (LLSD::array_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
{
LLSD& sdDict = *it;
tmp_app_path = (sdDict.has("name")) ? app_path + sdDict["name"].asString() : LLStringUtil::null;
tmp_user_path = (sdDict.has("name")) ? user_path + sdDict["name"].asString() : LLStringUtil::null;
sdDict["installed"] =
(!tmp_app_path.empty()) && ((gDirUtilp->fileExists(tmp_user_path + ".dic")) || (gDirUtilp->fileExists(tmp_app_path + ".dic")));
}
sSettingsChangeSignal();
}
void LLSpellChecker::addToCustomDictionary(const std::string& word)
{
if (mHunspell)
{
mHunspell->add(word.c_str());
}
addToDictFile(getDictionaryUserPath() + DICT_FILE_CUSTOM, word);
sSettingsChangeSignal();
}
void LLSpellChecker::addToIgnoreList(const std::string& word)
{
std::string word_lower(word);
LLStringUtil::toLower(word_lower);
if (mIgnoreList.end() == std::find(mIgnoreList.begin(), mIgnoreList.end(), word_lower))
{
mIgnoreList.push_back(word_lower);
addToDictFile(getDictionaryUserPath() + DICT_FILE_IGNORE, word_lower);
sSettingsChangeSignal();
}
}
void LLSpellChecker::addToDictFile(const std::string& dict_path, const std::string& word)
{
std::vector<std::string> word_list;
if (gDirUtilp->fileExists(dict_path))
{
llifstream file_in(dict_path, std::ios::in);
if (file_in.is_open())
{
std::string word; int line_num = 0;
while (getline(file_in, word))
{
// Skip over the first line since that's just a line count
if (0 != line_num)
{
word_list.push_back(word);
}
line_num++;
}
}
else
{
// TODO: show error message?
return;
}
}
word_list.push_back(word);
llofstream file_out(dict_path, std::ios::out | std::ios::trunc);
if (file_out.is_open())
{
file_out << word_list.size() << std::endl;
for (std::vector<std::string>::const_iterator itWord = word_list.begin(); itWord != word_list.end(); ++itWord)
{
file_out << *itWord << std::endl;
}
file_out.close();
}
}
bool LLSpellChecker::isActiveDictionary(const std::string& dict_language) const
{
return
(mDictLanguage == dict_language) ||
(mDictSecondary.end() != std::find(mDictSecondary.begin(), mDictSecondary.end(), dict_language));
}
void LLSpellChecker::setSecondaryDictionaries(dict_list_t dict_list)
{
if (!getUseSpellCheck())
{
return;
}
// Check if we're only adding secondary dictionaries, or removing them
dict_list_t dict_add(llmax(dict_list.size(), mDictSecondary.size())), dict_rem(llmax(dict_list.size(), mDictSecondary.size()));
dict_list.sort();
mDictSecondary.sort();
dict_list_t::iterator end_added = std::set_difference(dict_list.begin(), dict_list.end(), mDictSecondary.begin(), mDictSecondary.end(), dict_add.begin());
dict_list_t::iterator end_removed = std::set_difference(mDictSecondary.begin(), mDictSecondary.end(), dict_list.begin(), dict_list.end(), dict_rem.begin());
if (end_removed != dict_rem.begin()) // We can't remove secondary dictionaries so we need to recreate the Hunspell instance
{
mDictSecondary = dict_list;
std::string dict_language = mDictLanguage;
initHunspell(dict_language);
}
else if (end_added != dict_add.begin()) // Add the new secondary dictionaries one by one
{
const std::string app_path = getDictionaryAppPath();
const std::string user_path = getDictionaryUserPath();
for (dict_list_t::const_iterator it_added = dict_add.begin(); it_added != end_added; ++it_added)
{
const LLSD dict_entry = getDictionaryData(*it_added);
if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) )
{
continue;
}
const std::string strFileDic = dict_entry["name"].asString() + ".dic";
if (gDirUtilp->fileExists(user_path + strFileDic))
{
mHunspell->add_dic((user_path + strFileDic).c_str());
}
else if (gDirUtilp->fileExists(app_path + strFileDic))
{
mHunspell->add_dic((app_path + strFileDic).c_str());
}
}
mDictSecondary = dict_list;
sSettingsChangeSignal();
}
}
void LLSpellChecker::initHunspell(const std::string& dict_language)
{
if (mHunspell)
{
delete mHunspell;
mHunspell = NULL;
mDictLanguage.clear();
mDictFile.clear();
mIgnoreList.clear();
}
const LLSD dict_entry = (!dict_language.empty()) ? getDictionaryData(dict_language) : LLSD();
if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) || (!dict_entry["is_primary"].asBoolean()))
{
sSettingsChangeSignal();
return;
}
const std::string app_path = getDictionaryAppPath();
const std::string user_path = getDictionaryUserPath();
if (dict_entry.has("name"))
{
const std::string filename_aff = dict_entry["name"].asString() + ".aff";
const std::string filename_dic = dict_entry["name"].asString() + ".dic";
if ( (gDirUtilp->fileExists(user_path + filename_aff)) && (gDirUtilp->fileExists(user_path + filename_dic)) )
{
mHunspell = new Hunspell((user_path + filename_aff).c_str(), (user_path + filename_dic).c_str());
}
else if ( (gDirUtilp->fileExists(app_path + filename_aff)) && (gDirUtilp->fileExists(app_path + filename_dic)) )
{
mHunspell = new Hunspell((app_path + filename_aff).c_str(), (app_path + filename_dic).c_str());
}
if (!mHunspell)
{
return;
}
mDictLanguage = dict_language;
mDictFile = dict_entry["name"].asString();
if (gDirUtilp->fileExists(user_path + DICT_FILE_CUSTOM))
{
mHunspell->add_dic((user_path + DICT_FILE_CUSTOM).c_str());
}
if (gDirUtilp->fileExists(user_path + DICT_FILE_IGNORE))
{
llifstream file_in(user_path + DICT_FILE_IGNORE, std::ios::in);
if (file_in.is_open())
{
std::string word; int idxLine = 0;
while (getline(file_in, word))
{
// Skip over the first line since that's just a line count
if (0 != idxLine)
{
LLStringUtil::toLower(word);
mIgnoreList.push_back(word);
}
idxLine++;
}
}
}
for (dict_list_t::const_iterator it = mDictSecondary.begin(); it != mDictSecondary.end(); ++it)
{
const LLSD dict_entry = getDictionaryData(*it);
if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) )
{
continue;
}
const std::string filename_dic = dict_entry["name"].asString() + ".dic";
if (gDirUtilp->fileExists(user_path + filename_dic))
{
mHunspell->add_dic((user_path + filename_dic).c_str());
}
else if (gDirUtilp->fileExists(app_path + filename_dic))
{
mHunspell->add_dic((app_path + filename_dic).c_str());
}
}
}
sSettingsChangeSignal();
}
// static
const std::string LLSpellChecker::getDictionaryAppPath()
{
std::string dict_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, DICT_DIR, "");
return dict_path;
}
// static
const std::string LLSpellChecker::getDictionaryUserPath()
{
std::string dict_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, DICT_DIR, "");
if (!gDirUtilp->fileExists(dict_path))
{
LLFile::mkdir(dict_path);
}
return dict_path;
}
// static
bool LLSpellChecker::getUseSpellCheck()
{
return (LLSpellChecker::instanceExists()) && (LLSpellChecker::instance().mHunspell);
}
// static
bool LLSpellChecker::canRemoveDictionary(const std::string& dict_language)
{
// Only user-installed inactive dictionaries can be removed
const LLSD dict_info = getDictionaryData(dict_language);
return
(dict_info["user_installed"].asBoolean()) &&
( (!getUseSpellCheck()) || (!LLSpellChecker::instance().isActiveDictionary(dict_language)) );
}
// static
void LLSpellChecker::removeDictionary(const std::string& dict_language)
{
if (!canRemoveDictionary(dict_language))
{
return;
}
LLSD dict_map = loadUserDictionaryMap();
for (LLSD::array_const_iterator it = dict_map.beginArray(); it != dict_map.endArray(); ++it)
{
const LLSD& dict_info = *it;
if (dict_info["language"].asString() == dict_language)
{
const std::string dict_dic = getDictionaryUserPath() + dict_info["name"].asString() + ".dic";
if (gDirUtilp->fileExists(dict_dic))
{
LLFile::remove(dict_dic);
}
const std::string dict_aff = getDictionaryUserPath() + dict_info["name"].asString() + ".aff";
if (gDirUtilp->fileExists(dict_aff))
{
LLFile::remove(dict_aff);
}
dict_map.erase(it - dict_map.beginArray());
break;
}
}
saveUserDictionaryMap(dict_map);
refreshDictionaryMap();
}
// static
LLSD LLSpellChecker::loadUserDictionaryMap()
{
LLSD dict_map;
llifstream dict_file(getDictionaryUserPath() + DICT_FILE_USER, std::ios::binary);
if (dict_file.is_open())
{
LLSDSerialize::fromXMLDocument(dict_map, dict_file);
dict_file.close();
}
return dict_map;
}
// static
void LLSpellChecker::saveUserDictionaryMap(const LLSD& dict_map)
{
llofstream dict_file(getDictionaryUserPath() + DICT_FILE_USER, std::ios::trunc);
if (dict_file.is_open())
{
LLSDSerialize::toPrettyXML(dict_map, dict_file);
dict_file.close();
}
}
// static
boost::signals2::connection LLSpellChecker::setSettingsChangeCallback(const settings_change_signal_t::slot_type& cb)
{
return sSettingsChangeSignal.connect(cb);
}
// static
void LLSpellChecker::setUseSpellCheck(const std::string& dict_language)
{
if ( (((dict_language.empty()) && (getUseSpellCheck())) || (!dict_language.empty())) &&
(LLSpellChecker::instance().mDictLanguage != dict_language) )
{
LLSpellChecker::instance().initHunspell(dict_language);
}
}
// static
void LLSpellChecker::initClass()
{
if (sDictMap.isUndefined())
{
refreshDictionaryMap();
}
}

93
indra/llui/llspellcheck.h Normal file
View File

@ -0,0 +1,93 @@
/**
* @file llspellcheck.h
* @brief Spell checking functionality
*
* $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 LLSPELLCHECK_H
#define LLSPELLCHECK_H
#include "llsingleton.h"
#include "llui.h"
#include <boost/signals2.hpp>
class Hunspell;
class LLSpellChecker : public LLSingleton<LLSpellChecker>, public LLInitClass<LLSpellChecker>
{
friend class LLSingleton<LLSpellChecker>;
friend class LLInitClass<LLSpellChecker>;
protected:
LLSpellChecker();
~LLSpellChecker();
public:
void addToCustomDictionary(const std::string& word);
void addToIgnoreList(const std::string& word);
bool checkSpelling(const std::string& word) const;
S32 getSuggestions(const std::string& word, std::vector<std::string>& suggestions) const;
protected:
void addToDictFile(const std::string& dict_path, const std::string& word);
void initHunspell(const std::string& dict_language);
public:
typedef std::list<std::string> dict_list_t;
const std::string& getPrimaryDictionary() const { return mDictLanguage; }
const dict_list_t& getSecondaryDictionaries() const { return mDictSecondary; }
bool isActiveDictionary(const std::string& dict_language) const;
void setSecondaryDictionaries(dict_list_t dict_list);
static bool canRemoveDictionary(const std::string& dict_language);
static const std::string getDictionaryAppPath();
static const std::string getDictionaryUserPath();
static const LLSD getDictionaryData(const std::string& dict_language);
static const LLSD& getDictionaryMap() { return sDictMap; }
static bool getUseSpellCheck();
static bool hasDictionary(const std::string& dict_language, bool check_installed = false);
static void refreshDictionaryMap();
static void removeDictionary(const std::string& dict_language);
static void setUseSpellCheck(const std::string& dict_language);
protected:
static LLSD loadUserDictionaryMap();
static void setDictionaryData(const LLSD& dict_info);
static void saveUserDictionaryMap(const LLSD& dict_map);
public:
typedef boost::signals2::signal<void()> settings_change_signal_t;
static boost::signals2::connection setSettingsChangeCallback(const settings_change_signal_t::slot_type& cb);
protected:
static void initClass();
protected:
Hunspell* mHunspell;
std::string mDictLanguage;
std::string mDictFile;
dict_list_t mDictSecondary;
std::vector<std::string> mIgnoreList;
static LLSD sDictMap;
static settings_change_signal_t sSettingsChangeSignal;
};
#endif // LLSPELLCHECK_H

View File

@ -0,0 +1,46 @@
/**
* @file llspellcheckmenuhandler.h
* @brief Interface used by spell check menu handling
*
* $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 LLSPELLCHECKMENUHANDLER_H
#define LLSPELLCHECKMENUHANDLER_H
class LLSpellCheckMenuHandler
{
public:
virtual bool getSpellCheck() const { return false; }
virtual const std::string& getSuggestion(U32 index) const { return LLStringUtil::null; }
virtual U32 getSuggestionCount() const { return 0; }
virtual void replaceWithSuggestion(U32 index){}
virtual void addToDictionary() {}
virtual bool canAddToDictionary() const { return false; }
virtual void addToIgnore() {}
virtual bool canAddToIgnore() const { return false; }
};
#endif // LLSPELLCHECKMENUHANDLER_H

View File

@ -32,6 +32,7 @@
#include "lllocalcliprect.h"
#include "llmenugl.h"
#include "llscrollcontainer.h"
#include "llspellcheck.h"
#include "llstl.h"
#include "lltextparser.h"
#include "lltextutil.h"
@ -155,6 +156,7 @@ LLTextBase::Params::Params()
plain_text("plain_text",false),
track_end("track_end", false),
read_only("read_only", false),
spellcheck("spellcheck", false),
v_pad("v_pad", 0),
h_pad("h_pad", 0),
clip("clip", true),
@ -181,6 +183,9 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mFontShadow(p.font_shadow),
mPopupMenu(NULL),
mReadOnly(p.read_only),
mSpellCheck(p.spellcheck),
mSpellCheckStart(-1),
mSpellCheckEnd(-1),
mCursorColor(p.cursor_color),
mFgColor(p.text_color),
mBorderVisible( p.border_visible ),
@ -246,6 +251,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
addChild(mDocumentView);
}
if (mSpellCheck)
{
LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLTextBase::onSpellCheckSettingsChange, this));
}
mSpellCheckTimer.reset();
createDefaultSegment();
updateRects();
@ -541,8 +552,92 @@ void LLTextBase::drawText()
return;
}
// Perform spell check if needed
if ( (getSpellCheck()) && (getWText().length() > 2) )
{
// Calculate start and end indices for the spell checking range
S32 start = line_start, end = getLineEnd(last_line);
if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
{
const LLWString& wstrText = getWText();
mMisspellRanges.clear();
segment_set_t::const_iterator seg_it = getSegIterContaining(start);
while (mSegments.end() != seg_it)
{
LLTextSegmentPtr text_segment = *seg_it;
if ( (text_segment.isNull()) || (text_segment->getStart() >= end) )
{
break;
}
if (!text_segment->canEdit())
{
++seg_it;
continue;
}
// Combine adjoining text segments into one
U32 seg_start = text_segment->getStart(), seg_end = llmin(text_segment->getEnd(), end);
while (mSegments.end() != ++seg_it)
{
text_segment = *seg_it;
if ( (text_segment.isNull()) || (!text_segment->canEdit()) || (text_segment->getStart() >= end) )
{
break;
}
seg_end = llmin(text_segment->getEnd(), end);
}
// Find the start of the first word
U32 word_start = seg_start, word_end = -1;
while ( (word_start < wstrText.length()) && (!LLStringOps::isAlpha(wstrText[word_start])) )
{
word_start++;
}
// Iterate over all words in the text block and check them one by one
while (word_start < seg_end)
{
// Find the end of the current word (special case handling for "'" when it's used as a contraction)
word_end = word_start + 1;
while ( (word_end < seg_end) &&
((LLWStringUtil::isPartOfWord(wstrText[word_end])) ||
((L'\'' == wstrText[word_end]) &&
(LLStringOps::isAlnum(wstrText[word_end - 1])) && (LLStringOps::isAlnum(wstrText[word_end + 1])))) )
{
word_end++;
}
if (word_end > seg_end)
{
break;
}
// Don't process words shorter than 3 characters
std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
{
mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
}
// Find the start of the next word
word_start = word_end + 1;
while ( (word_start < seg_end) && (!LLWStringUtil::isPartOfWord(wstrText[word_start])) )
{
word_start++;
}
}
}
mSpellCheckStart = start;
mSpellCheckEnd = end;
}
}
LLTextSegmentPtr cur_segment = *seg_iter;
std::list<std::pair<U32, U32> >::const_iterator misspell_it = std::lower_bound(mMisspellRanges.begin(), mMisspellRanges.end(), std::pair<U32, U32>(line_start, 0));
for (S32 cur_line = first_line; cur_line < last_line; cur_line++)
{
S32 next_line = cur_line + 1;
@ -577,7 +672,8 @@ void LLTextBase::drawText()
cur_segment = *seg_iter;
}
S32 clipped_end = llmin( line_end, cur_segment->getEnd() ) - cur_segment->getStart();
S32 seg_end = llmin(line_end, cur_segment->getEnd());
S32 clipped_end = seg_end - cur_segment->getStart();
if (mUseEllipses // using ellipses
&& clipped_end == line_end // last segment on line
@ -589,6 +685,46 @@ void LLTextBase::drawText()
text_rect.mRight -= 2;
}
// Draw squiggly lines under any visible misspelled words
while ( (mMisspellRanges.end() != misspell_it) && (misspell_it->first < seg_end) && (misspell_it->second > seg_start) )
{
// Skip the current word if the user is still busy editing it
if ( (!mSpellCheckTimer.hasExpired()) && (misspell_it->first <= (U32)mCursorPos) && (misspell_it->second >= (U32)mCursorPos) )
{
++misspell_it;
continue;
}
U32 misspell_start = llmax<U32>(misspell_it->first, seg_start), misspell_end = llmin<U32>(misspell_it->second, seg_end);
S32 squiggle_start = 0, squiggle_end = 0, pony = 0;
cur_segment->getDimensions(seg_start - cur_segment->getStart(), misspell_start - seg_start, squiggle_start, pony);
cur_segment->getDimensions(misspell_start - cur_segment->getStart(), misspell_end - misspell_start, squiggle_end, pony);
squiggle_start += text_rect.mLeft;
pony = (squiggle_end + 3) / 6;
squiggle_start += squiggle_end / 2 - pony * 3;
squiggle_end = squiggle_start + pony * 6;
S32 squiggle_bottom = text_rect.mBottom + (S32)cur_segment->getStyle()->getFont()->getDescenderHeight();
gGL.color4ub(255, 0, 0, 200);
while (squiggle_start + 1 < squiggle_end)
{
gl_line_2d(squiggle_start, squiggle_bottom, squiggle_start + 2, squiggle_bottom - 2);
if (squiggle_start + 3 < squiggle_end)
{
gl_line_2d(squiggle_start + 2, squiggle_bottom - 3, squiggle_start + 4, squiggle_bottom - 1);
}
squiggle_start += 4;
}
if (misspell_it->second > seg_end)
{
break;
}
++misspell_it;
}
text_rect.mLeft = (S32)(cur_segment->draw(seg_start - cur_segment->getStart(), clipped_end, selection_left, selection_right, text_rect));
seg_start = clipped_end + cur_segment->getStart();
@ -1108,6 +1244,99 @@ void LLTextBase::deselect()
mIsSelecting = FALSE;
}
bool LLTextBase::getSpellCheck() const
{
return (LLSpellChecker::getUseSpellCheck()) && (!mReadOnly) && (mSpellCheck);
}
const std::string& LLTextBase::getSuggestion(U32 index) const
{
return (index < mSuggestionList.size()) ? mSuggestionList[index] : LLStringUtil::null;
}
U32 LLTextBase::getSuggestionCount() const
{
return mSuggestionList.size();
}
void LLTextBase::replaceWithSuggestion(U32 index)
{
for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
{
if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
{
deselect();
// Delete the misspelled word
removeStringNoUndo(it->first, it->second - it->first);
// Insert the suggestion in its place
LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index]));
setCursorPos(it->first + (S32)suggestion.length());
break;
}
}
mSpellCheckStart = mSpellCheckEnd = -1;
}
void LLTextBase::addToDictionary()
{
if (canAddToDictionary())
{
LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos));
}
}
bool LLTextBase::canAddToDictionary() const
{
return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
}
void LLTextBase::addToIgnore()
{
if (canAddToIgnore())
{
LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos));
}
}
bool LLTextBase::canAddToIgnore() const
{
return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
}
std::string LLTextBase::getMisspelledWord(U32 pos) const
{
for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
{
if ( (it->first <= pos) && (it->second >= pos) )
{
return wstring_to_utf8str(getWText().substr(it->first, it->second - it->first));
}
}
return LLStringUtil::null;
}
bool LLTextBase::isMisspelledWord(U32 pos) const
{
for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
{
if ( (it->first <= pos) && (it->second >= pos) )
{
return true;
}
}
return false;
}
void LLTextBase::onSpellCheckSettingsChange()
{
// Recheck the spelling on every change
mMisspellRanges.clear();
mSpellCheckStart = mSpellCheckEnd = -1;
}
// Sets the scrollbar from the cursor position
void LLTextBase::updateScrollFromCursor()
@ -1707,9 +1936,6 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
while ( LLUrlRegistry::instance().findUrl(text, match,
boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) )
{
LLTextUtil::processUrlMatch(&match,this);
start = match.getStart();
end = match.getEnd()+1;
@ -1745,6 +1971,8 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
}
LLTextUtil::processUrlMatch(&match,this);
// move on to the rest of the text after the Url
if (end < (S32)text.length())
{

View File

@ -30,6 +30,7 @@
#include "v4color.h"
#include "lleditmenuhandler.h"
#include "llspellcheckmenuhandler.h"
#include "llstyle.h"
#include "llkeywords.h"
#include "llpanel.h"
@ -230,7 +231,8 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
///
class LLTextBase
: public LLUICtrl,
protected LLEditMenuHandler
protected LLEditMenuHandler,
public LLSpellCheckMenuHandler
{
public:
friend class LLTextSegment;
@ -259,6 +261,7 @@ public:
border_visible,
track_end,
read_only,
spellcheck,
allow_scroll,
plain_text,
wrap,
@ -311,6 +314,24 @@ public:
/*virtual*/ BOOL canDeselect() const;
/*virtual*/ void deselect();
// LLSpellCheckMenuHandler overrides
/*virtual*/ bool getSpellCheck() const;
/*virtual*/ const std::string& getSuggestion(U32 index) const;
/*virtual*/ U32 getSuggestionCount() const;
/*virtual*/ void replaceWithSuggestion(U32 index);
/*virtual*/ void addToDictionary();
/*virtual*/ bool canAddToDictionary() const;
/*virtual*/ void addToIgnore();
/*virtual*/ bool canAddToIgnore() const;
// Spell checking helper functions
std::string getMisspelledWord(U32 pos) const;
bool isMisspelledWord(U32 pos) const;
void onSpellCheckSettingsChange();
// used by LLTextSegment layout code
bool getWordWrap() { return mWordWrap; }
bool getUseEllipses() { return mUseEllipses; }
@ -540,6 +561,14 @@ protected:
BOOL mIsSelecting; // Are we in the middle of a drag-select?
// spell checking
bool mSpellCheck;
S32 mSpellCheckStart;
S32 mSpellCheckEnd;
LLTimer mSpellCheckTimer;
std::list<std::pair<U32, U32> > mMisspellRanges;
std::vector<std::string> mSuggestionList;
// configuration
S32 mHPad; // padding on left of text
S32 mVPad; // padding above text

View File

@ -54,6 +54,7 @@
#include "llwindow.h"
#include "lltextparser.h"
#include "llscrollcontainer.h"
#include "llspellcheck.h"
#include "llpanel.h"
#include "llurlregistry.h"
#include "lltooltip.h"
@ -77,6 +78,7 @@ template class LLTextEditor* LLView::getChild<class LLTextEditor>(
const S32 UI_TEXTEDITOR_LINE_NUMBER_MARGIN = 32;
const S32 UI_TEXTEDITOR_LINE_NUMBER_DIGITS = 4;
const S32 SPACES_PER_TAB = 4;
const F32 SPELLCHECK_DELAY = 0.5f; // delay between the last keypress and spell checking the word the cursor is on
///////////////////////////////////////////////////////////////////
@ -1953,7 +1955,38 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)
S32 screen_x, screen_y;
localPointToScreen(x, y, &screen_x, &screen_y);
mContextMenu->show(screen_x, screen_y);
setCursorAtLocalPos(x, y, false);
if (hasSelection())
{
if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) )
{
deselect();
}
else
{
setCursorPos(llmax(mSelectionStart, mSelectionEnd));
}
}
bool use_spellcheck = getSpellCheck(), is_misspelled = false;
if (use_spellcheck)
{
mSuggestionList.clear();
// If the cursor is on a misspelled word, retrieve suggestions for it
std::string misspelled_word = getMisspelledWord(mCursorPos);
if ((is_misspelled = !misspelled_word.empty()) == true)
{
LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList);
}
}
mContextMenu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
mContextMenu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
mContextMenu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
mContextMenu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
mContextMenu->show(screen_x, screen_y, this);
}
@ -2838,6 +2871,9 @@ void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& cal
void LLTextEditor::onKeyStroke()
{
mKeystrokeSignal(this);
mSpellCheckStart = mSpellCheckEnd = -1;
mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
//virtual

View File

@ -46,7 +46,7 @@ LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10
// Class Implementation
//
LLKeyboard::LLKeyboard() : mCallbacks(NULL), mNumpadDistinct(ND_NUMLOCK_OFF)
LLKeyboard::LLKeyboard() : mCallbacks(NULL)
{
S32 i;

View File

@ -62,14 +62,6 @@ class LLWindowCallbacks;
class LLKeyboard
{
public:
typedef enum e_numpad_distinct
{
ND_NEVER,
ND_NUMLOCK_OFF,
ND_NUMLOCK_ON
} ENumpadDistinct;
public:
LLKeyboard();
virtual ~LLKeyboard();
@ -107,8 +99,6 @@ public:
static BOOL keyFromString(const std::string& str, KEY *key); // False on failure
static std::string stringFromKey(KEY key);
static std::string stringFromAccelerator( MASK accel_mask, KEY key );
e_numpad_distinct getNumpadDistinct() { return mNumpadDistinct; }
void setNumpadDistinct(e_numpad_distinct val) { mNumpadDistinct = val; }
void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; }
F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed.
@ -135,8 +125,6 @@ protected:
static LLKeyStringTranslatorFunc* mStringTranslator; // Used for l10n + PC/Mac/Linux accelerator labeling
e_numpad_distinct mNumpadDistinct;
EKeyboardInsertMode mInsertMode;
static std::map<KEY,std::string> sKeysToNames;

View File

@ -299,28 +299,11 @@ void LLKeyboardMacOSX::scanKeyboard()
BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key )
{
if(mNumpadDistinct == ND_NUMLOCK_ON)
{
std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
if(iter != mTranslateNumpadMap.end())
{
*translated_key = iter->second;
return TRUE;
}
}
return translateKey(os_key, translated_key);
}
U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key)
{
if(mNumpadDistinct == ND_NUMLOCK_ON)
{
std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
if(iter != mInvTranslateNumpadMap.end())
{
return iter->second;
}
}
return inverseTranslateKey(translated_key);
}

View File

@ -312,29 +312,11 @@ void LLKeyboardSDL::scanKeyboard()
BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key)
{
if(mNumpadDistinct == ND_NUMLOCK_ON)
{
std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
if(iter != mTranslateNumpadMap.end())
{
*translated_key = iter->second;
return TRUE;
}
}
BOOL success = translateKey(os_key, translated_key);
return success;
return translateKey(os_key, translated_key);
}
U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)
{
if(mNumpadDistinct == ND_NUMLOCK_ON)
{
std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
if(iter != mInvTranslateNumpadMap.end())
{
return iter->second;
}
}
return inverseTranslateKey(translated_key);
}

View File

@ -299,69 +299,13 @@ void LLKeyboardWin32::scanKeyboard()
BOOL LLKeyboardWin32::translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key)
{
if(mNumpadDistinct == ND_NUMLOCK_ON)
{
std::map<U16, KEY>::iterator iter = mTranslateNumpadMap.find(os_key);
if (iter != mTranslateNumpadMap.end())
{
*translated_key = iter->second;
return TRUE;
}
}
BOOL success = translateKey(os_key, translated_key);
if(mNumpadDistinct != ND_NEVER) {
if(!success) return success;
if(mask & MASK_EXTENDED)
{
// this is where we'd create new keycodes for extended keys
// the set of extended keys includes the 'normal' arrow keys and
// the pgup/dn/insert/home/end/delete cluster above the arrow keys
// see http://windowssdk.msdn.microsoft.com/en-us/library/ms646280.aspx
// only process the return key if numlock is off
if(((mNumpadDistinct == ND_NUMLOCK_OFF &&
!(GetKeyState(VK_NUMLOCK) & 1))
|| mNumpadDistinct == ND_NUMLOCK_ON) &&
*translated_key == KEY_RETURN) {
*translated_key = KEY_PAD_RETURN;
}
}
else
{
// the non-extended keys, those are in the numpad
switch (*translated_key)
{
case KEY_LEFT:
*translated_key = KEY_PAD_LEFT; break;
case KEY_RIGHT:
*translated_key = KEY_PAD_RIGHT; break;
case KEY_UP:
*translated_key = KEY_PAD_UP; break;
case KEY_DOWN:
*translated_key = KEY_PAD_DOWN; break;
case KEY_HOME:
*translated_key = KEY_PAD_HOME; break;
case KEY_END:
*translated_key = KEY_PAD_END; break;
case KEY_PAGE_UP:
*translated_key = KEY_PAD_PGUP; break;
case KEY_PAGE_DOWN:
*translated_key = KEY_PAD_PGDN; break;
case KEY_INSERT:
*translated_key = KEY_PAD_INS; break;
case KEY_DELETE:
*translated_key = KEY_PAD_DEL; break;
}
}
}
return success;
return translateKey(os_key, translated_key);
}
U16 LLKeyboardWin32::inverseTranslateExtendedKey(const KEY translated_key)
{
// if numlock is on, then we need to translate KEY_PAD_FOO to the corresponding number pad number
if((mNumpadDistinct == ND_NUMLOCK_ON) && (GetKeyState(VK_NUMLOCK) & 1))
if(GetKeyState(VK_NUMLOCK) & 1)
{
std::map<KEY, U16>::iterator iter = mInvTranslateNumpadMap.find(translated_key);
if (iter != mInvTranslateNumpadMap.end())

View File

@ -1702,6 +1702,12 @@ void LLWindowWin32::initCursors()
mCursor[ UI_CURSOR_TOOLSIT ] = LoadCursor(module, TEXT("TOOLSIT"));
mCursor[ UI_CURSOR_TOOLBUY ] = LoadCursor(module, TEXT("TOOLBUY"));
mCursor[ UI_CURSOR_TOOLOPEN ] = LoadCursor(module, TEXT("TOOLOPEN"));
mCursor[ UI_CURSOR_TOOLPATHFINDING ] = LoadCursor(module, TEXT("TOOLPATHFINDING"));
mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTARTADD"));
mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTART"));
mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHEND"));
mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHENDADD"));
mCursor[ UI_CURSOR_TOOLNO ] = LoadCursor(module, TEXT("TOOLNO"));
// Color cursors
mCursor[ UI_CURSOR_TOOLPLAY ] = loadColorCursor(TEXT("TOOLPLAY"));

View File

@ -201,7 +201,8 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value)
}
LLSD storable_value = getComparableValue(new_value);
bool value_changed = llsd_compare(getValue(), storable_value) == FALSE;
LLSD original_value = getValue();
bool value_changed = llsd_compare(original_value, storable_value) == FALSE;
if(saved_value)
{
// If we're going to save this value, return to default but don't fire
@ -237,7 +238,7 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value)
if(value_changed)
{
mCommitSignal(this, storable_value);
firePropertyChanged(original_value);
}
}
@ -249,12 +250,13 @@ void LLControlVariable::setDefaultValue(const LLSD& value)
// *NOTE: Default values are not saved, only read.
LLSD comparable_value = getComparableValue(value);
bool value_changed = (llsd_compare(getValue(), comparable_value) == FALSE);
LLSD original_value = getValue();
bool value_changed = (llsd_compare(original_value, comparable_value) == FALSE);
resetToDefault(false);
mValues[0] = comparable_value;
if(value_changed)
{
firePropertyChanged();
firePropertyChanged(original_value);
}
}
@ -277,6 +279,8 @@ void LLControlVariable::resetToDefault(bool fire_signal)
{
//The first setting is always the default
//Pop to it and fire off the listener
LLSD originalValue = mValues.back();
while(mValues.size() > 1)
{
mValues.pop_back();
@ -284,7 +288,7 @@ void LLControlVariable::resetToDefault(bool fire_signal)
if(fire_signal)
{
firePropertyChanged();
firePropertyChanged(originalValue);
}
}

View File

@ -98,7 +98,7 @@ class LLControlVariable : public LLRefCount
public:
typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&, const LLSD&)> commit_signal_t;
private:
std::string mName;
@ -146,11 +146,11 @@ public:
void setHiddenFromSettingsEditor(bool hide);
void setComment(const std::string& comment);
void firePropertyChanged()
{
mCommitSignal(this, mValues.back());
}
private:
void firePropertyChanged(const LLSD &pPreviousValue)
{
mCommitSignal(this, mValues.back(), pPreviousValue);
}
LLSD getComparableValue(const LLSD& value);
bool llsd_compare(const LLSD& a, const LLSD & b);
};

View File

@ -13,16 +13,17 @@ include(EXPAT)
include(FMOD)
include(OPENAL)
include(FindOpenGL)
include(Hunspell)
include(JsonCpp)
include(LLAudio)
include(LLCharacter)
include(LLCommon)
include(LLConvexDecomposition)
include(LLImage)
include(LLImageJ2COJ)
include(LLInventory)
include(LLMath)
include(LLMessage)
include(LLPhysicsExtensions)
include(LLPlugin)
include(LLPrimitive)
include(LLRender)
@ -44,6 +45,8 @@ include(VisualLeakDetector)
include(GLOD)
include(CMakeCopyIfDifferent)
add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions)
include_directories(
${DBUSGLIB_INCLUDE_DIRS}
${JSONCPP_INCLUDE_DIR}
@ -51,13 +54,14 @@ include_directories(
${LLAUDIO_INCLUDE_DIRS}
${LLCHARACTER_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
${LLCONVEXDECOMP_INCLUDE_DIRS}
${LLPHYSICS_INCLUDE_DIRS}
${FMOD_INCLUDE_DIR}
${LLIMAGE_INCLUDE_DIRS}
${LLKDU_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
${LLPLUGIN_INCLUDE_DIRS}
${LLPRIMITIVE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
@ -70,6 +74,7 @@ include_directories(
${LLLOGIN_INCLUDE_DIRS}
${UPDATER_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILD_DIR}/include/hunspell
${OPENAL_LIB_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada/1.4
)
@ -96,6 +101,7 @@ set(viewer_SOURCE_FILES
llassetuploadresponders.cpp
llattachmentsmgr.cpp
llaudiosourcevo.cpp
llautoreplace.cpp
llavataractions.cpp
llavatariconctrl.cpp
llavatarlist.cpp
@ -167,6 +173,7 @@ set(viewer_SOURCE_FILES
llfloaterabout.cpp
llfloaterbvhpreview.cpp
llfloaterauction.cpp
llfloaterautoreplacesettings.cpp
llfloateravatar.cpp
llfloateravatarpicker.cpp
llfloateravatartextures.cpp
@ -210,12 +217,15 @@ set(viewer_SOURCE_FILES
llfloatermemleak.cpp
llfloatermodelpreview.cpp
llfloatermodeluploadbase.cpp
llfloatermodelwizard.cpp
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
llfloateroutbox.cpp
llfloaterpathfindingcharacters.cpp
llfloaterpathfindingconsole.cpp
llfloaterpathfindinglinksets.cpp
llfloaterpathfindingobjects.cpp
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
@ -232,6 +242,7 @@ set(viewer_SOURCE_FILES
llfloatersidepanelcontainer.cpp
llfloatersnapshot.cpp
llfloatersounddevices.cpp
llfloaterspellchecksettings.cpp
llfloatertelehub.cpp
llfloatertestinspectors.cpp
llfloatertestlistview.cpp
@ -384,6 +395,7 @@ set(viewer_SOURCE_FILES
llpanelonlinestatus.cpp
llpaneloutfitedit.cpp
llpaneloutfitsinventory.cpp
llpanelpathfindingrebakenavmesh.cpp
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
@ -412,6 +424,17 @@ set(viewer_SOURCE_FILES
llparcelselection.cpp
llparticipantlist.cpp
llpatchvertexarray.cpp
llpathfindingcharacter.cpp
llpathfindingcharacterlist.cpp
llpathfindinglinkset.cpp
llpathfindinglinksetlist.cpp
llpathfindingmanager.cpp
llpathfindingnavmesh.cpp
llpathfindingnavmeshstatus.cpp
llpathfindingnavmeshzone.cpp
llpathfindingobject.cpp
llpathfindingobjectlist.cpp
llpathfindingpathtool.cpp
llphysicsmotion.cpp
llphysicsshapebuilderutil.cpp
llplacesinventorybridge.cpp
@ -654,6 +677,7 @@ set(viewer_HEADER_FILES
llassetuploadresponders.h
llattachmentsmgr.h
llaudiosourcevo.h
llautoreplace.h
llavataractions.h
llavatariconctrl.h
llavatarlist.h
@ -725,6 +749,7 @@ set(viewer_HEADER_FILES
llfloaterabout.h
llfloaterbvhpreview.h
llfloaterauction.h
llfloaterautoreplacesettings.h
llfloateravatar.h
llfloateravatarpicker.h
llfloateravatartextures.h
@ -768,12 +793,15 @@ set(viewer_HEADER_FILES
llfloatermemleak.h
llfloatermodelpreview.h
llfloatermodeluploadbase.h
llfloatermodelwizard.h
llfloaternamedesc.h
llfloaternotificationsconsole.h
llfloaterobjectweights.h
llfloateropenobject.h
llfloateroutbox.h
llfloaterpathfindingcharacters.h
llfloaterpathfindingconsole.h
llfloaterpathfindinglinksets.h
llfloaterpathfindingobjects.h
llfloaterpay.h
llfloaterperms.h
llfloaterpostprocess.h
@ -790,6 +818,7 @@ set(viewer_HEADER_FILES
llfloatersidepanelcontainer.h
llfloatersnapshot.h
llfloatersounddevices.h
llfloaterspellchecksettings.h
llfloatertelehub.h
llfloatertestinspectors.h
llfloatertestlistview.h
@ -936,6 +965,7 @@ set(viewer_HEADER_FILES
llpanelonlinestatus.h
llpaneloutfitedit.h
llpaneloutfitsinventory.h
llpanelpathfindingrebakenavmesh.h
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
@ -959,6 +989,17 @@ set(viewer_HEADER_FILES
llparcelselection.h
llparticipantlist.h
llpatchvertexarray.h
llpathfindingcharacter.h
llpathfindingcharacterlist.h
llpathfindinglinkset.h
llpathfindinglinksetlist.h
llpathfindingmanager.h
llpathfindingnavmesh.h
llpathfindingnavmeshstatus.h
llpathfindingnavmeshzone.h
llpathfindingobject.h
llpathfindingobjectlist.h
llpathfindingpathtool.h
llphysicsmotion.h
llphysicsshapebuilderutil.h
llplacesinventorybridge.h
@ -1308,6 +1349,11 @@ if (WINDOWS)
res/lltoolgrab.cur
res/lltoolland.cur
res/lltoolpan.cur
res/lltoolpathfinding.cur
res/lltoolpathfindingpathend.cur
res/lltoolpathfindingpathendadd.cur
res/lltoolpathfindingpathstart.cur
res/lltoolpathfindingpathstartadd.cur
res/lltoolpipette.cur
res/lltoolrotate.cur
res/lltoolscale.cur
@ -1515,11 +1561,9 @@ set(PACKAGE ON CACHE BOOL
if (WINDOWS)
set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES
# *TODO -reenable this once we get server usage sorted out
#LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\""
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc"
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS}"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
LINK_FLAGS_RELEASE ""
LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF"
)
if(USE_PRECOMPILED_HEADERS)
set_target_properties(
@ -1536,7 +1580,7 @@ if (WINDOWS)
# In the meantime, if you have any ideas on how to easily maintain one list, either here or in viewer_manifest.py
# and have the build deps get tracked *please* tell me about it.
if(USE_GOOGLE_PERFTOOLS)
if(USE_TCMALLOC)
# Configure a var for tcmalloc location, if used.
# Note the need to specify multiple names explicitly.
set(GOOGLE_PERF_TOOLS_SOURCE
@ -1544,7 +1588,7 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libtcmalloc_minimal.dll
${SHARED_LIB_STAGING_DIR}/Debug/libtcmalloc_minimal-debug.dll
)
endif(USE_GOOGLE_PERFTOOLS)
endif(USE_TCMALLOC)
set(COPY_INPUT_DEPENDENCIES
@ -1574,6 +1618,9 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcp100.dll
${SHARED_LIB_STAGING_DIR}/Debug/msvcr100d.dll
${SHARED_LIB_STAGING_DIR}/Debug/msvcp100d.dll
${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp.dll
@ -1724,6 +1771,17 @@ if (WINDOWS)
#${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2)
endif (PACKAGE)
elseif (DARWIN)
set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES
LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP"
)
else (WINDOWS)
# Linux
set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES
LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Wl,--Map=${VIEWER_BINARY_NAME}.MAP"
)
endif (WINDOWS)
# *NOTE - this list is very sensitive to ordering, test carefully on all
@ -1752,6 +1810,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${NDOF_LIBRARY}
${HUNSPELL_LIBRARY}
${viewer_LIBRARIES}
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
@ -1770,7 +1829,8 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
${LLLOGIN_LIBRARIES}
${LLCONVEXDECOMP_LIBRARY}
${LLPHYSICS_LIBRARIES}
${LLPHYSICSEXTENSIONS_LIBRARIES}
${TCMALLOC_LIBRARIES}
)

File diff suppressed because it is too large Load Diff

View File

@ -101,7 +101,7 @@
<key>grid</key>
<map>
<key>desc</key>
<string>Specify the name of the grid, local, or an IP address to connect to.</string>
<string>Specify the name of the grid to connect to.</string>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
@ -117,16 +117,6 @@
<string>h</string>
</map>
<key>helperuri</key>
<map>
<key>desc</key>
<string>helper web CGI prefix to use</string>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
<string>CmdLineHelperURI</string>
</map>
<key>ignorepixeldepth</key>
<map>
<key>desc</key>
@ -163,7 +153,7 @@
<key>map-to</key>
<string>UserLogFile</string>
</map>
<key>login</key>
<map>
<key>desc</key>
@ -174,28 +164,6 @@
<string>UserLoginInfo</string>
</map>
<key>loginpage</key>
<map>
<key>desc</key>
<string>Login authentication page to use.</string>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
<string>LoginPage</string>
</map>
<key>loginuri</key>
<map>
<key>desc</key>
<string>login server and CGI script to use</string>
<key>count</key>
<integer>1</integer>
<key>compose</key>
<boolean>true</boolean>
<key>map-to</key>
<string>CmdLineLoginURI</string>
</map>
<key>logmetrics</key>
<map>
<key>desc</key>
@ -226,7 +194,7 @@
<map>
<key>map-to</key>
<string>NoAudio</string>
</map>
</map>
<key>noinvlib</key>
<map>
@ -242,7 +210,7 @@
<string>User will not get any notifications. NOTE: All notifications that occur will get added to ignore file for future runs.</string>
<key>map-to</key>
<string>IgnoreAllNotifications</string>
</map>
</map>
<key>nopreload</key>
<map>
@ -321,7 +289,7 @@
<key>map-to</key>
<string>QuitAfterSeconds</string>
</map>
<key>replaysession</key>
<map>
<key>desc</key>
@ -335,7 +303,7 @@
<key>map-to</key>
<string>RotateRight</string>
</map>
<key>safe</key>
<map>
<key>desc</key>

View File

@ -559,6 +559,98 @@ STATUS_NOT_SUPPORTED Feature not supported
STATUS_INTERNAL_ERROR An internal error occurred
STATUS_WHITELIST_FAILED URL failed to pass whitelist
PROFILE_NONE Disables profiling
PROFILE_SCRIPT_MEMORY Enables memory profiling
RC_DATA_FLAGS TODO: add documentation
RC_DETECT_PHANTOM TODO: add documentation
RC_GET_LINK_NUM TODO: add documentation
RC_GET_NORMAL TODO: add documentation
RC_GET_ROOT_KEY TODO: add documentation
RC_MAX_HITS TODO: add documentation
RC_REJECT_TYPES Optional parameter set in llCastRay() to reject hit against certain object types.
RC_REJECT_AGENTS Bit mask for RC_REJECT_TYPES, rejects hits against avatars.
RC_REJECT_PHYSICAL Bit mask for RC_REJECT_TYPES, rejects hits against moving objects.
RC_REJECT_NONPHYSICAL Bit mask for RC_REJECT_TYPES, rejects hits against non-moving objects.
RC_REJECT_LAND Bit mask for RC_REJECT_TYPES, rejects hits against the terrian.
RCERR_CAST_TIME_EXCEEDED TODO: add documentation
RCERR_SIM_PERF_LOW TODO: add documentation
RCERR_UNKNOWN TODO: add documentation
ESTATE_ACCESS_ALLOWED_AGENT_ADD TODO: add documentation
ESTATE_ACCESS_ALLOWED_AGENT_REMOVE TODO: add documentation
ESTATE_ACCESS_ALLOWED_GROUP_ADD TODO: add documentation
ESTATE_ACCESS_ALLOWED_GROUP_REMOVE TODO: add documentation
ESTATE_ACCESS_BANNED_AGENT_ADD TODO: add documentation
ESTATE_ACCESS_BANNED_AGENT_REMOVE TODO: add documentation
DENSITY TODO: add documentation
FRICTION TODO: add documentation
RESTITUTION TODO: add documentation
GRAVITY_MULTIPLIER TODO: add documentation
KFM_COMMAND TODO: add documentation
KFM_CMD_PLAY TODO: add documentation
KFM_CMD_STOP TODO: add documentation
KFM_CMD_PAUSE TODO: add documentation
KFM_CMD_SET_MODE TODO: add documentation
KFM_MODE TODO: add documentation
KFM_FORWARD TODO: add documentation
KFM_LOOP TODO: add documentation
KFM_PING_PONG TODO: add documentation
KFM_REVERSE TODO: add documentation
KFM_DATA TODO: add documentation
KFM_ROTATION TODO: add documentation
KFM_TRANSLATION TODO: add documentation
CHARACTER_CMD_STOP TODO: add documentation
CHARACTER_CMD_JUMP TODO: add documentation
CHARACTER_DESIRED_SPEED TODO: add documentation
CHARACTER_RADIUS TODO: add documentation
CHARACTER_LENGTH TODO: add documentation
CHARACTER_ORIENTATION TODO: add documentation
CHARACTER_AVOIDANCE_MODE TODO: add documentation
PURSUIT_OFFSET TODO: add documentation
REQUIRE_LINE_OF_SIGHT TODO: add documentation
PURSUIT_FUZZ_FACTOR TODO: add documentation
PURSUIT_INTERCEPT TODO: add documentation
FORCE_DIRECT_PATH TODO: add documentation
VERTICAL TODO: add documentation
HORIZONTAL TODO: add documentation
AVOID_CHARACTERS TODO: add documentation
AVOID_DYNAMIC_OBSTACLES TODO: add documentation
PU_EVADE_HIDDEN Triggered when an llEvade character thinks it has hidden from its pursuer.
PU_EVADE_SPOTTED Triggered when an llEvade character switches from hiding to running
PU_FAILURE_INVALID_GOAL Goal is not on the navigation-mesh and cannot be reached.
PU_FAILURE_INVALID_START Character cannot navigate from the current location - e.g., the character is off the navmesh or too high above it.
PU_FAILURE_NO_VALID_DESTINATION There's no good place for the character to go - e.g., it is patrolling and all the patrol points are now unreachable.
PU_FAILURE_OTHER Unknown failure
PU_FAILURE_TARGET_GONE Target (for llPursue or llEvade) can no longer be tracked - e.g., it left the region or is an avatar that is now more than about 30m outside the region.
PU_FAILURE_UNREACHABLE Goal is no longer reachable for some reason - e.g., an obstacle blocks the path.
PU_GOAL_REACHED Character has reached the goal and will stop or choose a new goal (if wandering).
PU_SLOWDOWN_DISTANCE_REACHED Character is near current goal.
CHARACTER_TYPE TODO: add documentation
CHARACTER_TYPE_A TODO: add documentation
CHARACTER_TYPE_B TODO: add documentation
CHARACTER_TYPE_C TODO: add documentation
CHARACTER_TYPE_D TODO: add documentation
CHARACTER_TYPE_NONE TODO: add documentation
TRAVERSAL_TYPE TODO: add documentation
TRAVERSAL_TYPE_SLOW TODO: add documentation
TRAVERSAL_TYPE_FAST TODO: add documentation
TRAVERSAL_TYPE_NONE TODO: add documentation
CHARACTER_MAX_ACCEL TODO: add documentation
CHARACTER_MAX_DECEL TODO: add documentation
CHARACTER_MAX_ANGULAR_SPEED TODO: add documentation
CHARACTER_MAX_ANGULAR_ACCEL TODO: add documentation
CHARACTER_TURN_SPEED_MULTIPLIER TODO: add documentation
# string constants
[word .1, .3, .5]
NULL_KEY Indicates an empty key

View File

@ -335,6 +335,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>AutoReplace</key>
<map>
<key>Comment</key>
<string>Replaces keywords with a configured word or phrase</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>AutoAcceptNewInventory</key>
<map>
<key>Comment</key>
@ -4292,6 +4303,17 @@
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryInboxToggleState</key>
<map>
<key>Comment</key>
<string>Stores the open/closed state of inventory Received items panel</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryLinking</key>
<map>
@ -6356,17 +6378,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>NumpadControl</key>
<map>
<key>Comment</key>
<string>How numpad keys control your avatar. 0 = Like the normal arrow keys, 1 = Numpad moves avatar when numlock is off, 2 = Numpad moves avatar regardless of numlock (use this if you have no numlock)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>ObjectCacheEnabled</key>
<map>
<key>Comment</key>
@ -10887,7 +10898,8 @@
<string>F32</string>
<key>Value</key>
<real>0.1</real>
</map> <key>ToolTipFadeTime</key>
</map>
<key>ToolTipFadeTime</key>
<map>
<key>Comment</key>
<string>Seconds over which tooltip fades away</string>
@ -12295,6 +12307,28 @@
<key>Value</key>
<real>10.0</real>
</map>
<key>SpellCheck</key>
<map>
<key>Comment</key>
<string>Enable spellchecking on line and text editors</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>SpellCheckDictionary</key>
<map>
<key>Comment</key>
<string>Current primary and secondary dictionaries used for spell checking</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>English (United States),Second Life Glossary</string>
</map>
<key>UseNewWalkRun</key>
<map>
<key>Comment</key>
@ -13630,5 +13664,312 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>PathfindingRetrieveNeighboringRegion</key>
<map>
<key>Comment</key>
<string>Download a neighboring region when visualizing a pathfinding navmesh (default val 99 means do not download neighbors).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>99</integer>
</map>
<key>PathfindingNavMeshClear</key>
<map>
<key>Comment</key>
<string>Background color when displaying pathfinding navmesh.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>0</real>
<real>0</real>
<real>0</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingWalkable</key>
<map>
<key>Comment</key>
<string>Color of walkable objects when displaying pathfinding navmesh object types.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>0.45490196078431372549019607843137</real>
<real>0.93333333333333333333333333333333</real>
<real>0.38823529411764705882352941176471</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingObstacle</key>
<map>
<key>Comment</key>
<string>Color of static obstacle objects when displaying pathfinding navmesh object types.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>1.0</real>
<real>0.0</real>
<real>0.0</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingMaterial</key>
<map>
<key>Comment</key>
<string>Color of material volumes when displaying pathfinding navmesh object types.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>0.5</real>
<real>0.0</real>
<real>1.0</real>
<real>0.3</real>
</array>
</map>
<key>PathfindingExclusion</key>
<map>
<key>Comment</key>
<string>Color of exclusion volumes when displaying pathfinding navmesh object types.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>1.0</real>
<real>1.0</real>
<real>0.0</real>
<real>0.3</real>
</array>
</map>
<key>PathfindingConnectedEdge</key>
<map>
<key>Comment</key>
<string>Color of a connected (crossable) edge when displaying pathfinding navmesh.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>0.86</real>
<real>0.86</real>
<real>0.86</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingBoundaryEdge</key>
<map>
<key>Comment</key>
<string>Color of a boundary (non-crossable) edge when displaying pathfinding navmesh.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>1.0</real>
<real>0.0</real>
<real>0.0</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingHeatColorBase</key>
<map>
<key>Comment</key>
<string>Color of the least walkable value when displaying the pathfinding navmesh as a heatmap.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>1.0</real>
<real>0.0</real>
<real>0.0</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingHeatColorMax</key>
<map>
<key>Comment</key>
<string>Color of the most walkable value when displaying the pathfinding navmesh as a heatmap.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>1.0</real>
<real>1.0</real>
<real>1.0</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingFaceColor</key>
<map>
<key>Comment</key>
<string>Color of the faces when displaying the default view of the pathfinding navmesh.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>1.0</real>
<real>1.0</real>
<real>1.0</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingTestPathValidEndColor</key>
<map>
<key>Comment</key>
<string>Color of the pathfinding test-pathing tool end-point when the path is valid.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>0.78</real>
<real>0.47</real>
<real>0.0</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingTestPathInvalidEndColor</key>
<map>
<key>Comment</key>
<string>Color of the pathfinding test-pathing tool end-point when the path is invalid.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>1.0</real>
<real>0.0</real>
<real>1.0</real>
<real>1.0</real>
</array>
</map>
<key>PathfindingTestPathColor</key>
<map>
<key>Comment</key>
<string>Color of the pathfinding test-path when the path is valid.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>1.0</real>
<real>0.59</real>
<real>0.0</real>
<real>0.9</real>
</array>
</map>
<key>PathfindingAmbiance</key>
<map>
<key>Comment</key>
<string>Ambiance of lit pathfinding navmesh displays.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.5</real>
</map>
<key>PathfindingXRayTint</key>
<map>
<key>Comment</key>
<string>Amount to darken/lighten x-ray lines in pathfinding display.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.8</real>
</map>
<key>PathfindingXRayOpacity</key>
<map>
<key>Comment</key>
<string>Opacity of xray lines in pathfinding display.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.25</real>
</map>
<key>PathfindingXRayWireframe</key>
<map>
<key>Comment</key>
<string>Render pathfinding navmesh xray as a wireframe.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>PathfindingLineWidth</key>
<map>
<key>Comment</key>
<string>Width of volume outlines in pathfinding navmesh display.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>2.0</real>
</map>
<key>PathfindingLineOffset</key>
<map>
<key>Comment</key>
<string>Depth offset of volume outlines in pathfinding display.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>2.3</real>
</map>
<key>PathfindingWaterColor</key>
<map>
<key>Comment</key>
<string>Color of water plane when displaying pathfinding navmesh.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Color4</string>
<key>Value</key>
<array>
<real>0.0</real>
<real>0.0</real>
<real>1.0</real>
<real>1.0</real>
</array>
</map>
</map>
</llsd>

View File

@ -0,0 +1,37 @@
/**
* @file pathfindingF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, 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$
*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
VARYING vec4 vertex_color;
void main()
{
frag_color = vertex_color;
}

View File

@ -0,0 +1,42 @@
/**
* @file pathfindingV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, 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$
*/
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
VARYING vec4 vertex_color;
uniform float tint;
uniform float alpha_scale;
void main()
{
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vertex_color = vec4(diffuse_color.rgb * tint, diffuse_color.a*alpha_scale);
}

View File

@ -0,0 +1,54 @@
/**
* @file pathfindingV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, 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$
*/
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 normal;
VARYING vec4 vertex_color;
uniform float tint;
uniform float ambiance;
uniform float alpha_scale;
void main()
{
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vec3 l1 = vec3(-0.75, 1, 1.0)*0.5;
vec3 l2 = vec3(0.5, -0.6, 0.4)*0.25;
vec3 l3 = vec3(0.5, -0.8, 0.3)*0.5;
float lit = max(dot(normal, l1), 0.0);
lit += max(dot(normal, l2), 0.0);
lit += max(dot(normal, l3), 0.0);
lit = clamp(lit, ambiance, 1.0);
vertex_color = vec4(diffuse_color.rgb * tint * lit, diffuse_color.a*alpha_scale);
}

View File

@ -56,6 +56,7 @@
#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
#include "llnearbychatbar.h"
#include "llnotificationsutil.h"
#include "llpanelpathfindingrebakenavmesh.h"
#include "llpaneltopinfobar.h"
#include "llparcel.h"
#include "llrendersphere.h"
@ -81,6 +82,7 @@
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
#include "llvoavatarself.h"
@ -112,6 +114,105 @@ const F32 MAX_FIDGET_TIME = 20.f; // seconds
// The agent instance.
LLAgent gAgent;
class LLTeleportRequest
{
public:
enum EStatus
{
kPending,
kStarted,
kFailed,
kRestartPending
};
LLTeleportRequest();
virtual ~LLTeleportRequest();
EStatus getStatus() const {return mStatus;};
void setStatus(EStatus pStatus) {mStatus = pStatus;};
virtual bool canRestartTeleport();
virtual void startTeleport() = 0;
virtual void restartTeleport();
protected:
private:
EStatus mStatus;
};
class LLTeleportRequestViaLandmark : public LLTeleportRequest
{
public:
LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
virtual ~LLTeleportRequestViaLandmark();
virtual bool canRestartTeleport();
virtual void startTeleport();
virtual void restartTeleport();
protected:
inline const LLUUID &getLandmarkId() const {return mLandmarkId;};
private:
LLUUID mLandmarkId;
};
class LLTeleportRequestViaLure : public LLTeleportRequestViaLandmark
{
public:
LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike);
virtual ~LLTeleportRequestViaLure();
virtual bool canRestartTeleport();
virtual void startTeleport();
protected:
inline BOOL isLureGodLike() const {return mIsLureGodLike;};
private:
BOOL mIsLureGodLike;
};
class LLTeleportRequestViaLocation : public LLTeleportRequest
{
public:
LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal);
virtual ~LLTeleportRequestViaLocation();
virtual bool canRestartTeleport();
virtual void startTeleport();
virtual void restartTeleport();
protected:
inline const LLVector3d &getPosGlobal() const {return mPosGlobal;};
private:
LLVector3d mPosGlobal;
};
class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation
{
public:
LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal);
virtual ~LLTeleportRequestViaLocationLookAt();
virtual bool canRestartTeleport();
virtual void startTeleport();
virtual void restartTeleport();
protected:
private:
};
//--------------------------------------------------------------------
// Statics
//
@ -243,8 +344,20 @@ LLAgent::LLAgent() :
mbTeleportKeepsLookAt(false),
mAgentAccess(new LLAgentAccess(gSavedSettings)),
mGodLevelChangeSignal(),
mCanEditParcel(false),
mTeleportSourceSLURL(new LLSLURL),
mTeleportRequest(),
mTeleportFinishedSlot(),
mTeleportFailedSlot(),
mIsMaturityRatingChangingDuringTeleport(false),
mMaturityRatingChange(0U),
mIsDoSendMaturityPreferenceToServer(false),
mMaturityPreferenceRequestId(0U),
mMaturityPreferenceResponseId(0U),
mMaturityPreferenceNumRetries(0U),
mLastKnownRequestMaturity(SIM_ACCESS_MIN),
mLastKnownResponseMaturity(SIM_ACCESS_MIN),
mTeleportState( TELEPORT_NONE ),
mRegionp(NULL),
@ -330,9 +443,21 @@ void LLAgent::init()
gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));
gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2));
mLastKnownResponseMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity"));
mLastKnownRequestMaturity = mLastKnownResponseMaturity;
mIsDoSendMaturityPreferenceToServer = true;
LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback));
if (!mTeleportFinishedSlot.connected())
{
mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this));
}
if (!mTeleportFailedSlot.connected())
{
mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this));
}
mInitialized = TRUE;
}
@ -342,6 +467,14 @@ void LLAgent::init()
void LLAgent::cleanup()
{
mRegionp = NULL;
if (mTeleportFinishedSlot.connected())
{
mTeleportFinishedSlot.disconnect();
}
if (mTeleportFailedSlot.connected())
{
mTeleportFailedSlot.disconnect();
}
}
//-----------------------------------------------------------------------------
@ -1869,6 +2002,7 @@ void LLAgent::endAnimationUpdateUI()
LLChicletBar::getInstance()->setVisible(TRUE);
LLPanelStandStopFlying::getInstance()->setVisible(TRUE);
LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(TRUE);
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
@ -1978,6 +2112,7 @@ void LLAgent::endAnimationUpdateUI()
LLChicletBar::getInstance()->setVisible(FALSE);
LLPanelStandStopFlying::getInstance()->setVisible(FALSE);
LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(FALSE);
// clear out camera lag effect
gAgentCamera.clearCameraLag();
@ -2371,49 +2506,278 @@ bool LLAgent::isAdult() const
return mAgentAccess->isAdult();
}
void LLAgent::setTeen(bool teen)
{
mAgentAccess->setTeen(teen);
}
//static
int LLAgent::convertTextToMaturity(char text)
{
return LLAgentAccess::convertTextToMaturity(text);
}
bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
{
if (!getRegion())
return false;
// Update agent access preference on the server
std::string url = getRegion()->getCapability("UpdateAgentInformation");
if (!url.empty())
public:
LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
virtual ~LLMaturityPreferencesResponder();
virtual void result(const LLSD &pContent);
virtual void error(U32 pStatus, const std::string& pReason);
protected:
private:
U8 parseMaturityFromServerResponse(const LLSD &pContent);
LLAgent *mAgent;
U8 mPreferredMaturity;
U8 mPreviousMaturity;
};
LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity)
: LLHTTPClient::Responder(),
mAgent(pAgent),
mPreferredMaturity(pPreferredMaturity),
mPreviousMaturity(pPreviousMaturity)
{
}
LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder()
{
}
void LLMaturityPreferencesResponder::result(const LLSD &pContent)
{
U8 actualMaturity = parseMaturityFromServerResponse(pContent);
if (actualMaturity != mPreferredMaturity)
{
// Set new access preference
LLSD access_prefs = LLSD::emptyMap();
if (preferredMaturity == SIM_ACCESS_PG)
{
access_prefs["max"] = "PG";
}
else if (preferredMaturity == SIM_ACCESS_MATURE)
{
access_prefs["max"] = "M";
}
if (preferredMaturity == SIM_ACCESS_ADULT)
{
access_prefs["max"] = "A";
}
LLSD body = LLSD::emptyMap();
body["access_prefs"] = access_prefs;
llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: "
<< url << llendl;
LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); // Ignore response
return true;
llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '"
<< LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast<U32>(actualMaturity) << ", llsd:"
<< pContent << "]" << llendl;
}
mAgent->handlePreferredMaturityResult(actualMaturity);
}
void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason)
{
llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '"
<< pReason << "' [status:" << pStatus << "]" << llendl;
mAgent->handlePreferredMaturityError();
}
U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
{
// stinson 05/24/2012 Pathfinding regions have re-defined the response behavior. In the old server code,
// if you attempted to change the preferred maturity to the same value, the response content would be an
// undefined LLSD block. In the new server code with pathfinding, the response content should always be
// defined. Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged
// into server trunk and fully deployed.
U8 maturity = SIM_ACCESS_MIN;
if (pContent.isUndefined())
{
maturity = mPreferredMaturity;
}
else
{
llassert(!pContent.isUndefined());
llassert(pContent.isMap());
if (!pContent.isUndefined() && pContent.isMap())
{
// stinson 05/24/2012 Pathfinding regions have re-defined the response syntax. The if statement catches
// the new syntax, and the else statement catches the old syntax. After pathfinding is merged into
// server trunk and fully deployed, we can remove the else statement.
if (pContent.has("access_prefs"))
{
llassert(pContent.has("access_prefs"));
llassert(pContent.get("access_prefs").isMap());
llassert(pContent.get("access_prefs").has("max"));
llassert(pContent.get("access_prefs").get("max").isString());
if (pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") &&
pContent.get("access_prefs").get("max").isString())
{
LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
LLStringUtil::trim(actualPreference);
maturity = LLViewerRegion::shortStringToAccess(actualPreference);
}
}
else if (pContent.has("max"))
{
llassert(pContent.get("max").isString());
if (pContent.get("max").isString())
{
LLSD::String actualPreference = pContent.get("max").asString();
LLStringUtil::trim(actualPreference);
maturity = LLViewerRegion::shortStringToAccess(actualPreference);
}
}
}
}
return maturity;
}
void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
{
// Update the number of responses received
++mMaturityPreferenceResponseId;
llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId);
// Update the last known server maturity response
mLastKnownResponseMaturity = pServerMaturity;
// Ignore all responses if we know there are more unanswered requests that are expected
if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId)
{
// If we received a response that matches the last known request, then we are good
if (mLastKnownRequestMaturity == mLastKnownResponseMaturity)
{
mMaturityPreferenceNumRetries = 0;
reportPreferredMaturitySuccess();
llassert(static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")) == mLastKnownResponseMaturity);
}
// Else, the viewer is out of sync with the server, so let's try to re-sync with the
// server by re-sending our last known request. Cap the re-tries at 3 just to be safe.
else if (++mMaturityPreferenceNumRetries <= 3)
{
llinfos << "Retrying attempt #" << mMaturityPreferenceNumRetries << " to set viewer preferred maturity to '"
<< LLViewerRegion::accessToString(mLastKnownRequestMaturity) << "'" << llendl;
sendMaturityPreferenceToServer(mLastKnownRequestMaturity);
}
// Else, the viewer is style out of sync with the server after 3 retries, so inform the user
else
{
mMaturityPreferenceNumRetries = 0;
reportPreferredMaturityError();
}
}
}
void LLAgent::handlePreferredMaturityError()
{
// Update the number of responses received
++mMaturityPreferenceResponseId;
llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId);
// Ignore all responses if we know there are more unanswered requests that are expected
if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId)
{
mMaturityPreferenceNumRetries = 0;
// If we received a response that matches the last known request, then we are synced with
// the server, but not quite sure why we are
if (mLastKnownRequestMaturity == mLastKnownResponseMaturity)
{
llwarns << "Got an error but maturity preference '" << LLViewerRegion::accessToString(mLastKnownRequestMaturity)
<< "' seems to be in sync with the server" << llendl;
reportPreferredMaturitySuccess();
}
// Else, the more likely case is that the last request does not match the last response,
// so inform the user
else
{
reportPreferredMaturityError();
}
}
}
void LLAgent::reportPreferredMaturitySuccess()
{
// If there is a pending teleport request waiting for the maturity preference to be synced with
// the server, let's start the pending request
if (hasPendingTeleportRequest())
{
startTeleportRequest();
}
}
void LLAgent::reportPreferredMaturityError()
{
// If there is a pending teleport request waiting for the maturity preference to be synced with
// the server, we were unable to successfully sync with the server on maturity preference, so let's
// just raise the screen.
mIsMaturityRatingChangingDuringTeleport = false;
if (hasPendingTeleportRequest())
{
setTeleportState(LLAgent::TELEPORT_NONE);
}
// Get the last known maturity request from the user activity
std::string preferredMaturity = LLViewerRegion::accessToString(mLastKnownRequestMaturity);
LLStringUtil::toLower(preferredMaturity);
// Get the last known maturity response from the server
std::string actualMaturity = LLViewerRegion::accessToString(mLastKnownResponseMaturity);
LLStringUtil::toLower(actualMaturity);
// Notify the user
LLSD args = LLSD::emptyMap();
args["PREFERRED_MATURITY"] = preferredMaturity;
args["ACTUAL_MATURITY"] = actualMaturity;
LLNotificationsUtil::add("MaturityChangeError", args);
// Check the saved settings to ensure that we are consistent. If we are not consistent, update
// the viewer, but do not send anything to server
U8 localMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity"));
if (localMaturity != mLastKnownResponseMaturity)
{
bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer;
mIsDoSendMaturityPreferenceToServer = false;
llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(mLastKnownResponseMaturity) << "'" << llendl;
gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(mLastKnownResponseMaturity));
mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer;
}
}
bool LLAgent::isMaturityPreferenceSyncedWithServer() const
{
return (mMaturityPreferenceRequestId == mMaturityPreferenceResponseId);
}
void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
{
// Only send maturity preference to the server if enabled
if (mIsDoSendMaturityPreferenceToServer)
{
// Increment the number of requests. The handlers manage a separate count of responses.
++mMaturityPreferenceRequestId;
// Update the last know maturity request
mLastKnownRequestMaturity = pPreferredMaturity;
// Create a response handler
LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity));
// If we don't have a region, report it as an error
if (getRegion() == NULL)
{
responderPtr->error(0U, "region is not defined");
}
else
{
// Find the capability to send maturity preference
std::string url = getRegion()->getCapability("UpdateAgentInformation");
// If the capability is not defined, report it as an error
if (url.empty())
{
responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region");
}
else
{
// Set new access preference
LLSD access_prefs = LLSD::emptyMap();
access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
LLSD body = LLSD::emptyMap();
body["access_prefs"] = access_prefs;
llinfos << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity)
<< "' via capability to: " << url << llendl;
LLSD headers;
LLHTTPClient::post(url, body, responderPtr, headers, 30.0f);
}
}
}
return false;
}
BOOL LLAgent::getAdminOverride() const
@ -2434,11 +2798,12 @@ void LLAgent::setAdminOverride(BOOL b)
void LLAgent::setGodLevel(U8 god_level)
{
mAgentAccess->setGodLevel(god_level);
mGodLevelChangeSignal(god_level);
}
void LLAgent::setAOTransition()
LLAgent::god_level_change_slot_t LLAgent::registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback)
{
mAgentAccess->setTransition();
return mGodLevelChangeSignal.connect(pGodLevelChangeCallback);
}
const LLAgentAccess& LLAgent::getAgentAccess()
@ -2451,9 +2816,9 @@ bool LLAgent::validateMaturity(const LLSD& newvalue)
return mAgentAccess->canSetMaturity(newvalue.asInteger());
}
void LLAgent::handleMaturity(const LLSD& newvalue)
void LLAgent::handleMaturity(const LLSD &pNewValue)
{
sendMaturityPreferenceToServer(newvalue.asInteger());
sendMaturityPreferenceToServer(static_cast<U8>(pNewValue.asInteger()));
}
//----------------------------------------------------------------------------
@ -3388,7 +3753,7 @@ void LLAgent::clearVisualParams(void *data)
// protected
bool LLAgent::teleportCore(bool is_local)
{
if(TELEPORT_NONE != mTeleportState)
if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING))
{
llwarns << "Attempt to teleport when already teleporting." << llendl;
return false;
@ -3466,6 +3831,102 @@ bool LLAgent::teleportCore(bool is_local)
return true;
}
bool LLAgent::hasRestartableFailedTeleportRequest()
{
return ((mTeleportRequest != NULL) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed) &&
mTeleportRequest->canRestartTeleport());
}
void LLAgent::restartFailedTeleportRequest()
{
if (hasRestartableFailedTeleportRequest())
{
mTeleportRequest->setStatus(LLTeleportRequest::kRestartPending);
startTeleportRequest();
}
}
void LLAgent::clearTeleportRequest()
{
mTeleportRequest.reset();
}
void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
{
mIsMaturityRatingChangingDuringTeleport = true;
mMaturityRatingChange = pMaturityRatingChange;
}
bool LLAgent::hasPendingTeleportRequest()
{
return ((mTeleportRequest != NULL) &&
((mTeleportRequest->getStatus() == LLTeleportRequest::kPending) ||
(mTeleportRequest->getStatus() == LLTeleportRequest::kRestartPending)));
}
void LLAgent::startTeleportRequest()
{
if (hasPendingTeleportRequest())
{
if (!isMaturityPreferenceSyncedWithServer())
{
gTeleportDisplay = TRUE;
setTeleportState(TELEPORT_PENDING);
}
else
{
switch (mTeleportRequest->getStatus())
{
case LLTeleportRequest::kPending :
mTeleportRequest->setStatus(LLTeleportRequest::kStarted);
mTeleportRequest->startTeleport();
break;
case LLTeleportRequest::kRestartPending :
llassert(mTeleportRequest->canRestartTeleport());
mTeleportRequest->setStatus(LLTeleportRequest::kStarted);
mTeleportRequest->restartTeleport();
break;
default :
llassert(0);
break;
}
}
}
}
void LLAgent::handleTeleportFinished()
{
clearTeleportRequest();
if (mIsMaturityRatingChangingDuringTeleport)
{
// notify user that the maturity preference has been changed
std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange);
LLStringUtil::toLower(maturityRating);
LLSD args;
args["RATING"] = maturityRating;
LLNotificationsUtil::add("PreferredMaturityChanged", args);
mIsMaturityRatingChangingDuringTeleport = false;
}
}
void LLAgent::handleTeleportFailed()
{
if (mTeleportRequest != NULL)
{
mTeleportRequest->setStatus(LLTeleportRequest::kFailed);
}
if (mIsMaturityRatingChangingDuringTeleport)
{
// notify user that the maturity preference has been changed
std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange);
LLStringUtil::toLower(maturityRating);
LLSD args;
args["RATING"] = maturityRating;
LLNotificationsUtil::add("PreferredMaturityChanged", args);
mIsMaturityRatingChangingDuringTeleport = false;
}
}
void LLAgent::teleportRequest(
const U64& region_handle,
const LLVector3& pos_local,
@ -3497,6 +3958,12 @@ void LLAgent::teleportRequest(
// Landmark ID = LLUUID::null means teleport home
void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
{
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id));
startTeleportRequest();
}
void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
{
LLViewerRegion *regionp = getRegion();
if(regionp && teleportCore())
@ -3512,6 +3979,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
}
void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
{
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike));
startTeleportRequest();
}
void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
{
LLViewerRegion* regionp = getRegion();
if(regionp && teleportCore())
@ -3544,23 +4017,32 @@ void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
// James Cook, July 28, 2005
void LLAgent::teleportCancel()
{
LLViewerRegion* regionp = getRegion();
if(regionp)
if (!hasPendingTeleportRequest())
{
// send the message
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("TeleportCancel");
msg->nextBlockFast(_PREHASH_Info);
msg->addUUIDFast(_PREHASH_AgentID, getID());
msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
sendReliableMessage();
}
gTeleportDisplay = FALSE;
LLViewerRegion* regionp = getRegion();
if(regionp)
{
// send the message
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("TeleportCancel");
msg->nextBlockFast(_PREHASH_Info);
msg->addUUIDFast(_PREHASH_AgentID, getID());
msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
sendReliableMessage();
}
}
clearTeleportRequest();
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
}
void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
{
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global));
startTeleportRequest();
}
void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
{
LLViewerRegion* regionp = getRegion();
U64 handle = to_region_handle(pos_global);
@ -3603,6 +4085,12 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
// Teleport to global position, but keep facing in the same direction
void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global)
{
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global));
startTeleportRequest();
}
void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global)
{
mbTeleportKeepsLookAt = true;
gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction
@ -4045,5 +4533,149 @@ LLAgentQueryManager::~LLAgentQueryManager()
{
}
// EOF
//-----------------------------------------------------------------------------
// LLTeleportRequest
//-----------------------------------------------------------------------------
LLTeleportRequest::LLTeleportRequest()
: mStatus(kPending)
{
}
LLTeleportRequest::~LLTeleportRequest()
{
}
bool LLTeleportRequest::canRestartTeleport()
{
return false;
}
void LLTeleportRequest::restartTeleport()
{
llassert(0);
}
//-----------------------------------------------------------------------------
// LLTeleportRequestViaLandmark
//-----------------------------------------------------------------------------
LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId)
: LLTeleportRequest(),
mLandmarkId(pLandmarkId)
{
}
LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
{
}
bool LLTeleportRequestViaLandmark::canRestartTeleport()
{
return true;
}
void LLTeleportRequestViaLandmark::startTeleport()
{
gAgent.doTeleportViaLandmark(getLandmarkId());
}
void LLTeleportRequestViaLandmark::restartTeleport()
{
gAgent.doTeleportViaLandmark(getLandmarkId());
}
//-----------------------------------------------------------------------------
// LLTeleportRequestViaLure
//-----------------------------------------------------------------------------
LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike)
: LLTeleportRequestViaLandmark(pLureId),
mIsLureGodLike(pIsLureGodLike)
{
}
LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
{
}
bool LLTeleportRequestViaLure::canRestartTeleport()
{
// stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions
// The current scenario is as follows:
// 1. User A initializes a request for User B to teleport via lure
// 2. User B accepts the teleport via lure request
// 3. The server sees the init request from User A and the accept request from User B and matches them up
// 4. The server then removes the paired requests up from the "queue"
// 5. The server then fails User B's teleport for reason of maturity level (for example)
// 6. User B's viewer prompts user to increase their maturity level profile value.
// 7. User B confirms and accepts increase in maturity level
// 8. User B's viewer then attempts to teleport via lure again
// 9. This request will time-out on the viewer-side because User A's initial request has been removed from the "queue" in step 4
return false;
}
void LLTeleportRequestViaLure::startTeleport()
{
gAgent.doTeleportViaLure(getLandmarkId(), isLureGodLike());
}
//-----------------------------------------------------------------------------
// LLTeleportRequestViaLocation
//-----------------------------------------------------------------------------
LLTeleportRequestViaLocation::LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal)
: LLTeleportRequest(),
mPosGlobal(pPosGlobal)
{
}
LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation()
{
}
bool LLTeleportRequestViaLocation::canRestartTeleport()
{
return true;
}
void LLTeleportRequestViaLocation::startTeleport()
{
gAgent.doTeleportViaLocation(getPosGlobal());
}
void LLTeleportRequestViaLocation::restartTeleport()
{
gAgent.doTeleportViaLocation(getPosGlobal());
}
//-----------------------------------------------------------------------------
// LLTeleportRequestViaLocationLookAt
//-----------------------------------------------------------------------------
LLTeleportRequestViaLocationLookAt::LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal)
: LLTeleportRequestViaLocation(pPosGlobal)
{
}
LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt()
{
}
bool LLTeleportRequestViaLocationLookAt::canRestartTeleport()
{
return true;
}
void LLTeleportRequestViaLocationLookAt::startTeleport()
{
gAgent.doTeleportViaLocationLookAt(getPosGlobal());
}
void LLTeleportRequestViaLocationLookAt::restartTeleport()
{
gAgent.doTeleportViaLocationLookAt(getPosGlobal());
}
// EOF

View File

@ -35,6 +35,8 @@
#include "llcoordframe.h" // for mFrameAgent
#include "llvoavatardefines.h"
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/signals2.hpp>
extern const BOOL ANIMATE;
@ -56,6 +58,9 @@ class LLAgentAccess;
class LLSLURL;
class LLPauseRequestHandle;
class LLUIColor;
class LLTeleportRequest;
typedef boost::shared_ptr<LLTeleportRequest> LLTeleportRequestPtr;
//--------------------------------------------------------------------
// Types
@ -539,7 +544,8 @@ public:
TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator
TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator
TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches"
TELEPORT_LOCAL = 6 // Teleporting in-sim without showing the progress screen
TELEPORT_LOCAL = 6, // Teleporting in-sim without showing the progress screen
TELEPORT_PENDING = 7
};
public:
@ -556,9 +562,6 @@ private:
// Teleport Actions
//--------------------------------------------------------------------
public:
void teleportRequest(const U64& region_handle,
const LLVector3& pos_local, // Go to a named location home
bool look_at_from_camera = false);
void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark
void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home
void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location
@ -569,6 +572,44 @@ public:
protected:
bool teleportCore(bool is_local = false); // Stuff for all teleports; returns true if the teleport can proceed
//--------------------------------------------------------------------
// Teleport State
//--------------------------------------------------------------------
public:
bool hasRestartableFailedTeleportRequest();
void restartFailedTeleportRequest();
void clearTeleportRequest();
void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
private:
friend class LLTeleportRequest;
friend class LLTeleportRequestViaLandmark;
friend class LLTeleportRequestViaLure;
friend class LLTeleportRequestViaLocation;
friend class LLTeleportRequestViaLocationLookAt;
LLTeleportRequestPtr mTeleportRequest;
boost::signals2::connection mTeleportFinishedSlot;
boost::signals2::connection mTeleportFailedSlot;
bool mIsMaturityRatingChangingDuringTeleport;
U8 mMaturityRatingChange;
bool hasPendingTeleportRequest();
void startTeleportRequest();
void teleportRequest(const U64& region_handle,
const LLVector3& pos_local, // Go to a named location home
bool look_at_from_camera = false);
void doTeleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark
void doTeleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location
void doTeleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated
void doTeleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation
void handleTeleportFinished();
void handleTeleportFailed();
//--------------------------------------------------------------------
// Teleport State
//--------------------------------------------------------------------
@ -614,8 +655,6 @@ public:
const LLAgentAccess& getAgentAccess();
BOOL canManageEstate() const;
BOOL getAdminOverride() const;
// ! BACKWARDS COMPATIBILITY ! This function can go away after the AO transition (see llstartup.cpp).
void setAOTransition();
private:
LLAgentAccess * mAgentAccess;
@ -631,6 +670,16 @@ public:
void requestEnterGodMode();
void requestLeaveGodMode();
typedef boost::function<void (U8)> god_level_change_callback_t;
typedef boost::signals2::signal<void (U8)> god_level_change_signal_t;
typedef boost::signals2::connection god_level_change_slot_t;
god_level_change_slot_t registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback);
private:
god_level_change_signal_t mGodLevelChangeSignal;
//--------------------------------------------------------------------
// Maturity
//--------------------------------------------------------------------
@ -650,13 +699,28 @@ public:
bool isTeen() const;
bool isMature() const;
bool isAdult() const;
void setTeen(bool teen);
void setMaturity(char text);
static int convertTextToMaturity(char text);
bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"?
static int convertTextToMaturity(char text);
private:
bool mIsDoSendMaturityPreferenceToServer;
unsigned int mMaturityPreferenceRequestId;
unsigned int mMaturityPreferenceResponseId;
unsigned int mMaturityPreferenceNumRetries;
U8 mLastKnownRequestMaturity;
U8 mLastKnownResponseMaturity;
bool isMaturityPreferenceSyncedWithServer() const;
void sendMaturityPreferenceToServer(U8 pPreferredMaturity);
friend class LLMaturityPreferencesResponder;
void handlePreferredMaturityResult(U8 pServerMaturity);
void handlePreferredMaturityError();
void reportPreferredMaturitySuccess();
void reportPreferredMaturityError();
// Maturity callbacks for PreferredMaturity control variable
void handleMaturity(const LLSD& newvalue);
void handleMaturity(const LLSD &pNewValue);
bool validateMaturity(const LLSD& newvalue);

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