Compare commits
359 Commits
animesh
...
sv-1.8.7.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9548270306 | ||
|
|
44aec1384a | ||
|
|
42139835d5 | ||
|
|
49f0f8e28f | ||
|
|
36b75b2398 | ||
|
|
9a53824d6d | ||
|
|
a9e2672820 | ||
|
|
138cf5d4f8 | ||
|
|
4b2e358783 | ||
|
|
851b3659ee | ||
|
|
27d4e05f2b | ||
|
|
deade4438d | ||
|
|
deafc6814d | ||
|
|
1fd6e91c68 | ||
|
|
67126ab494 | ||
|
|
e3318fb0d2 | ||
|
|
e9d28ee5c1 | ||
|
|
2ffc99aecf | ||
|
|
450afff50b | ||
|
|
570b0d3c5b | ||
|
|
09daa2a865 | ||
|
|
e97837e103 | ||
|
|
84add2d864 | ||
|
|
4c224def62 | ||
|
|
2242a1d101 | ||
|
|
b957c0930d | ||
|
|
f7434711ad | ||
|
|
5f0b23edd7 | ||
|
|
2eff62ad0d | ||
|
|
686795618a | ||
|
|
5c8c5a2c45 | ||
|
|
d98b99f7b3 | ||
|
|
8d472a9c7b | ||
|
|
3747d79143 | ||
|
|
910a5557ab | ||
|
|
8163448a6c | ||
|
|
ac0e93dcad | ||
|
|
ed420c3645 | ||
|
|
b872860443 | ||
|
|
992f4c7b5d | ||
|
|
8f15478ba4 | ||
|
|
1c371e7be6 | ||
|
|
937c80f694 | ||
|
|
15bd41bd71 | ||
|
|
b9156b7955 | ||
|
|
623a484ae3 | ||
|
|
2ace698101 | ||
|
|
34e0c722e7 | ||
|
|
82ee06a6bd | ||
|
|
584ee8fffe | ||
|
|
d80d232ee5 | ||
|
|
de47736038 | ||
|
|
0da16e6034 | ||
|
|
6c9a156610 | ||
|
|
1726c27078 | ||
|
|
64b43a47b5 | ||
|
|
8005a58ed5 | ||
|
|
d1d42701f5 | ||
|
|
c57fceff17 | ||
|
|
265336463d | ||
|
|
3ba1c88672 | ||
|
|
90e6afe159 | ||
|
|
3209507b6c | ||
|
|
fa97d8497a | ||
|
|
a687273d57 | ||
|
|
28f13b806c | ||
|
|
f1342d7bb8 | ||
|
|
c3428c6d57 | ||
|
|
0efddbd9ff | ||
|
|
be0aba4bfa | ||
|
|
c3f03b6bbf | ||
|
|
e15839a2cb | ||
|
|
e0efbd7d26 | ||
|
|
8e57288819 | ||
|
|
107f512545 | ||
|
|
14dc348179 | ||
|
|
eccbd98d79 | ||
|
|
a5115aa69e | ||
|
|
327574db7c | ||
|
|
8b4a29cbd3 | ||
|
|
544feee19f | ||
|
|
bee60da089 | ||
|
|
c466b44143 | ||
|
|
27222d524c | ||
|
|
b99e2cbbdd | ||
|
|
a5bdc24a14 | ||
|
|
0b6d94f202 | ||
|
|
bf5035388b | ||
|
|
640c136bcc | ||
|
|
6ebd2eef00 | ||
|
|
c954d02125 | ||
|
|
a34414849c | ||
|
|
c1ffb1b332 | ||
|
|
d06448cdfd | ||
|
|
117ef68916 | ||
|
|
83b384ab97 | ||
|
|
5ee5ba473b | ||
|
|
4055af4afd | ||
|
|
65dad7acfd | ||
|
|
a21927e510 | ||
|
|
094c948a87 | ||
|
|
31003f13af | ||
|
|
c1f39e167c | ||
|
|
0e28436aa9 | ||
|
|
bc1c816b99 | ||
|
|
32424e5640 | ||
|
|
760f1308f3 | ||
|
|
dfe8e364be | ||
|
|
33feeb0a01 | ||
|
|
50eb21ce23 | ||
|
|
d2052b9e4c | ||
|
|
2c5ad97697 | ||
|
|
8283422717 | ||
|
|
4a293ff1e1 | ||
|
|
828307ca96 | ||
|
|
a83901d2e4 | ||
|
|
878ba534b5 | ||
|
|
f17e6637d6 | ||
|
|
66b2ad5f30 | ||
|
|
463151c830 | ||
|
|
77b6a903ac | ||
|
|
1813a7bf8b | ||
|
|
6839cba56a | ||
|
|
f73fb6424b | ||
|
|
af2ae76ca2 | ||
|
|
a870534ea0 | ||
|
|
ba61314c32 | ||
|
|
d32e478456 | ||
|
|
1b29210f16 | ||
|
|
760f23b370 | ||
|
|
a7cba5f1a3 | ||
|
|
27033f4ebb | ||
|
|
c772179149 | ||
|
|
4c7eacf4fc | ||
|
|
672037d1f2 | ||
|
|
80cedb913a | ||
|
|
734621be82 | ||
|
|
dd3944161d | ||
|
|
1aabbb13c0 | ||
|
|
5574f263b1 | ||
|
|
2117c66c9a | ||
|
|
1fbfc498bf | ||
|
|
a02693e4dd | ||
|
|
24118e8e67 | ||
|
|
19ad64cc96 | ||
|
|
e81affce51 | ||
|
|
dec0bff972 | ||
|
|
5daf4aa777 | ||
|
|
2f24a53a01 | ||
|
|
28af96229b | ||
|
|
6d776632a9 | ||
|
|
1853500e10 | ||
|
|
8e01fcb7f0 | ||
|
|
3cddb0df2e | ||
|
|
37c4a4bbcb | ||
|
|
af8f0e1155 | ||
|
|
5df00a481d | ||
|
|
d299c55ea4 | ||
|
|
d9d83a6807 | ||
|
|
3fec94bb94 | ||
|
|
09926d12bb | ||
|
|
19bcdae6ac | ||
|
|
36025384f4 | ||
|
|
4bdbb89e6f | ||
|
|
e94314dc95 | ||
|
|
5dd68a4055 | ||
|
|
fff4e9b4b8 | ||
|
|
8a6f5b49a3 | ||
|
|
c8290b913e | ||
|
|
e6e6d811c6 | ||
|
|
cdc35b3c32 | ||
|
|
c68e00730e | ||
|
|
0496374328 | ||
|
|
6608dd0b8d | ||
|
|
432b4ab69d | ||
|
|
967b3646a6 | ||
|
|
4110d1975a | ||
|
|
b1862ce1c1 | ||
|
|
a432c3429c | ||
|
|
949190b48d | ||
|
|
6885bf6368 | ||
|
|
78f354925c | ||
|
|
a87b7603d1 | ||
|
|
1f3a232a9d | ||
|
|
99346d6486 | ||
|
|
067bd3cbd7 | ||
|
|
6e716fe3c5 | ||
|
|
831c7f53b2 | ||
|
|
1c5a829e82 | ||
|
|
4751949628 | ||
|
|
f8abafdefa | ||
|
|
4798d1e3b3 | ||
|
|
10140d143c | ||
|
|
f3609b06d7 | ||
|
|
f25577649a | ||
|
|
cf5586037e | ||
|
|
c6e3c31fae | ||
|
|
0c3e1f602a | ||
|
|
d3a35e3f8d | ||
|
|
b34bafc348 | ||
|
|
cdb316834a | ||
|
|
8b30e2e931 | ||
|
|
841bd0e515 | ||
|
|
90677188ec | ||
|
|
6d5df7c9af | ||
|
|
79e1830ba9 | ||
|
|
f0db784b46 | ||
|
|
ef5c9f0175 | ||
|
|
84081286f0 | ||
|
|
1b913443ad | ||
|
|
f5c19b9e5c | ||
|
|
5a561e03b8 | ||
|
|
ab207727fd | ||
|
|
b3231883f6 | ||
|
|
d9ff42ab3c | ||
|
|
fb20751330 | ||
|
|
c5bf72f0b3 | ||
|
|
cfdcb8b3df | ||
|
|
7d0cbf6d02 | ||
|
|
0b4f576c54 | ||
|
|
d93bed216a | ||
|
|
89abfe6f86 | ||
|
|
78fbc214ca | ||
|
|
fc649854ff | ||
|
|
60e71f5724 | ||
|
|
b78807e5ed | ||
|
|
4e39027958 | ||
|
|
b527918350 | ||
|
|
16a352c70a | ||
|
|
5035f9c3d6 | ||
|
|
a662318417 | ||
|
|
573934e505 | ||
|
|
927e86bdc9 | ||
|
|
cfa2c4e424 | ||
|
|
79bafbb943 | ||
|
|
36bfaf0f05 | ||
|
|
3d7da6e858 | ||
|
|
f81f374ab9 | ||
|
|
82050a5e46 | ||
|
|
9cf26e1fc2 | ||
|
|
fa869f21ad | ||
|
|
6af65004a5 | ||
|
|
d189aadd12 | ||
|
|
6048019926 | ||
|
|
021ba21b4f | ||
|
|
96b7612d73 | ||
|
|
7e8ebdb852 | ||
|
|
2e52fe64b8 | ||
|
|
8b367c8eab | ||
|
|
68481b8921 | ||
|
|
a5aeac312c | ||
|
|
d29d35ab23 | ||
|
|
20eb6a3eca | ||
|
|
54c4b1de83 | ||
|
|
d3572dd4ec | ||
|
|
696a5f967d | ||
|
|
3fa4f73b6f | ||
|
|
afbafbe689 | ||
|
|
18b02594cb | ||
|
|
8288de7f79 | ||
|
|
1693c97924 | ||
|
|
e3d69b4d8e | ||
|
|
f8eef33b7b | ||
|
|
d5af2588bc | ||
|
|
432bf03f0a | ||
|
|
2ba3ff852c | ||
|
|
76e9d912d6 | ||
|
|
29e71bec86 | ||
|
|
1d1857e5a7 | ||
|
|
8a2407ecbb | ||
|
|
05146faacf | ||
|
|
b7fb8fb0ca | ||
|
|
5ddab7d3b2 | ||
|
|
ebcbf79237 | ||
|
|
f5fd05a1e4 | ||
|
|
a644b2dee5 | ||
|
|
1d073cd0d9 | ||
|
|
a1e74c3286 | ||
|
|
a6cc7eda61 | ||
|
|
a36e128e57 | ||
|
|
daffb602bb | ||
|
|
0f28a1bd86 | ||
|
|
4043130f75 | ||
|
|
835083a741 | ||
|
|
daf63eb418 | ||
|
|
4d5e5e1635 | ||
|
|
15c3ff0544 | ||
|
|
68d19cd6fb | ||
|
|
ecc1730912 | ||
|
|
9c2d062886 | ||
|
|
7b3c3b9fab | ||
|
|
a37299b4ae | ||
|
|
0c2ec8cb71 | ||
|
|
7c2af68e3c | ||
|
|
c0ec1d2c9a | ||
|
|
28911f03a7 | ||
|
|
c65b0eb544 | ||
|
|
f11eb17313 | ||
|
|
453386a49a | ||
|
|
accd69386a | ||
|
|
610d592f5a | ||
|
|
2b955eb00d | ||
|
|
f38d200e93 | ||
|
|
0b1f605bba | ||
|
|
278b617290 | ||
|
|
27c259bf7c | ||
|
|
f520251935 | ||
|
|
aa888c704e | ||
|
|
bbd3cb3469 | ||
|
|
bd2c67e8ec | ||
|
|
b5afce0bbd | ||
|
|
c5f714def8 | ||
|
|
fdeb194d0e | ||
|
|
975f3b420e | ||
|
|
8d5f1191dd | ||
|
|
7c89a8b178 | ||
|
|
7c24e67c50 | ||
|
|
1cb9ea16da | ||
|
|
c4a9532784 | ||
|
|
43163b400d | ||
|
|
93e30f44c0 | ||
|
|
b6b44a2c86 | ||
|
|
cb53a4f923 | ||
|
|
85f147f679 | ||
|
|
17cb8bd764 | ||
|
|
b2eb4ea70c | ||
|
|
c6089637e7 | ||
|
|
2f72ed2e80 | ||
|
|
7b6a4d76a8 | ||
|
|
8c7e498861 | ||
|
|
9824cc7068 | ||
|
|
d16ff5cb5c | ||
|
|
0409a81e36 | ||
|
|
e0883b72dc | ||
|
|
b592b3c658 | ||
|
|
d277f1750d | ||
|
|
d54bf78c08 | ||
|
|
b1be8bb7f3 | ||
|
|
0b7061afb7 | ||
|
|
b132578692 | ||
|
|
c18bdddb60 | ||
|
|
6cd07b23f1 | ||
|
|
ab546f54ab | ||
|
|
11068eee38 | ||
|
|
f80e23ac5e | ||
|
|
513a4fd16c | ||
|
|
98b3c8a812 | ||
|
|
f5ffa65ea7 | ||
|
|
a559a09217 | ||
|
|
3cb831bb56 | ||
|
|
bce8a3b3cc | ||
|
|
65ee3a5345 | ||
|
|
3c8a8efc03 | ||
|
|
99facf6764 | ||
|
|
8f3b10875e | ||
|
|
33ef6cc3f7 | ||
|
|
d21e5db701 | ||
|
|
1c1e64f48f | ||
|
|
4b6d1934c3 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,10 +3,12 @@
|
||||
*.aps
|
||||
*.suo
|
||||
*.vshost.exe
|
||||
*/.vs
|
||||
/bin/
|
||||
/bin-release/
|
||||
/bin
|
||||
/bin-release
|
||||
/indra/out/
|
||||
/indra/viewer-*
|
||||
/indra/newview/vivox-runtime/
|
||||
/indra/newview/dbghelp.dll
|
||||
|
||||
166
.gitlab-ci.yml
Normal file
166
.gitlab-ci.yml
Normal file
@@ -0,0 +1,166 @@
|
||||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
VIEWER_USE_CRASHPAD: "TRUE"
|
||||
VIEWER_CRASHPAD_URL: $SENTRY_DSN
|
||||
|
||||
.win_build: &win_build
|
||||
stage: build
|
||||
tags:
|
||||
- autobuild
|
||||
- windows
|
||||
before_script:
|
||||
- pipenv install
|
||||
script:
|
||||
- If ($env:VIEWER_CHANNEL_TYPE -eq 'Project')
|
||||
{
|
||||
$env:VIEWER_CHANNEL_CODENAME = $env:CI_COMMIT_REF_NAME[8..100] -join ''
|
||||
}
|
||||
- pipenv run autobuild configure -c Release -- -DUSE_FMODSTUDIO=ON -DUSE_NVAPI=ON -DUSE_LTO=ON -DVS_DISABLE_FATAL_WARNINGS=ON
|
||||
- pipenv run autobuild build -c Release --no-configure
|
||||
- If ($env:VIEWER_USE_CRASHPAD -eq 'TRUE') {
|
||||
- Push-Location .\build-vc-*\newview\Release\
|
||||
- sentry-cli upload-dif --include-sources singularity-bin.exe singularity-bin.pdb crashpad_handler.exe crashpad_handler.pdb fmod.dll libcrypto-1_1.dll libcrypto-1_1.pdb libssl-1_1.dll libssl-1_1.pdb libcrypto-1_1-x64.dll libcrypto-1_1-x64.pdb libssl-1_1-x64.dll libssl-1_1-x64.pdb vcruntime140.dll msvcp140.dll libhunspell.dll libhunspell.pdb glod.dll
|
||||
- Pop-Location }
|
||||
artifacts:
|
||||
name: "$env:CI_COMMIT_REF_NAME-$env:CI_COMMIT_SHORT_SHA"
|
||||
expire_in: 2 week
|
||||
paths:
|
||||
- build-vc-*/newview/Release/build_data.json
|
||||
- build-vc-*/newview/Release/singularity-bin.pdb
|
||||
- build-vc-*/newview/Release/Singularity_*_Setup.exe
|
||||
|
||||
.beta_rules: &beta_rules
|
||||
only:
|
||||
- /^.*-beta$/
|
||||
except:
|
||||
- branches
|
||||
|
||||
.release_rules: &release_rules
|
||||
only:
|
||||
- /^.*-release$/
|
||||
except:
|
||||
- branches
|
||||
|
||||
build:master:windows32:
|
||||
<<: *win_build
|
||||
interruptible: true
|
||||
variables:
|
||||
AUTOBUILD_ADDRSIZE: 32
|
||||
VIEWER_CHANNEL_TYPE: Test
|
||||
VIEWER_USE_CRASHPAD: "FALSE"
|
||||
only:
|
||||
- schedules
|
||||
|
||||
build:master:windows64:
|
||||
<<: *win_build
|
||||
interruptible: true
|
||||
variables:
|
||||
AUTOBUILD_ADDRSIZE: 64
|
||||
VIEWER_CHANNEL_TYPE: Test
|
||||
VIEWER_USE_CRASHPAD: "FALSE"
|
||||
only:
|
||||
- schedules
|
||||
|
||||
build:project:windows32:
|
||||
<<: *win_build
|
||||
interruptible: true
|
||||
variables:
|
||||
AUTOBUILD_ADDRSIZE: 32
|
||||
VIEWER_CHANNEL_TYPE: Project
|
||||
VIEWER_USE_CRASHPAD: "FALSE"
|
||||
only:
|
||||
- /^project-.*$/
|
||||
|
||||
build:project:windows64:
|
||||
<<: *win_build
|
||||
interruptible: true
|
||||
variables:
|
||||
AUTOBUILD_ADDRSIZE: 64
|
||||
VIEWER_CHANNEL_TYPE: Project
|
||||
only:
|
||||
- /^project-.*$/
|
||||
|
||||
build:beta:windows32:
|
||||
<<: *win_build
|
||||
variables:
|
||||
AUTOBUILD_ADDRSIZE: 32
|
||||
VIEWER_CHANNEL_TYPE: Beta
|
||||
VIEWER_USE_CRASHPAD: "FALSE"
|
||||
<<: *beta_rules
|
||||
|
||||
build:beta:windows64:
|
||||
<<: *win_build
|
||||
variables:
|
||||
AUTOBUILD_ADDRSIZE: 64
|
||||
VIEWER_CHANNEL_TYPE: Beta
|
||||
<<: *beta_rules
|
||||
|
||||
build:release:windows32:
|
||||
<<: *win_build
|
||||
variables:
|
||||
AUTOBUILD_ADDRSIZE: 32
|
||||
VIEWER_CHANNEL_TYPE: Release
|
||||
VIEWER_USE_CRASHPAD: "FALSE"
|
||||
<<: *release_rules
|
||||
|
||||
build:release:windows64:
|
||||
<<: *win_build
|
||||
variables:
|
||||
AUTOBUILD_ADDRSIZE: 64
|
||||
VIEWER_CHANNEL_TYPE: Release
|
||||
<<: *release_rules
|
||||
|
||||
.deploy_template: &deploy_template
|
||||
stage: deploy
|
||||
tags:
|
||||
- autobuild
|
||||
- windows
|
||||
script:
|
||||
- $BuildData = Get-Content .\build-vc-64\newview\Release\build_data.json | ConvertFrom-Json
|
||||
- $BuildChannelVersion = $BuildData."Channel" + ' ' + $BuildData."Version"
|
||||
- $UploadDestViewerDir = $BuildChannelVersion.ToLower().Replace(" ", "/")
|
||||
- $UploadDestURL = "https://pkg.alchemyviewer.org/repository/viewer/${UploadDestViewerDir}"
|
||||
|
||||
- $UploadParams = @{ UseBasicParsing = $true;
|
||||
Method = "PUT";
|
||||
Headers = @{
|
||||
ContentType = "application/x-executable";
|
||||
Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$env:AUTOBUILD_HTTP_USER`:$env:AUTOBUILD_HTTP_PASS")))"; };
|
||||
Verbose = $true; };
|
||||
|
||||
- Push-Location .\build-vc-32\newview\Release\
|
||||
- $FileNameWin32 = Get-ChildItem -Path . -Name -Include Singularity_*_Setup.exe
|
||||
- Invoke-WebRequest @UploadParams -InFile .\$FileNameWin32 -Uri "${UploadDestURL}/${FileNameWin32}"
|
||||
- Pop-Location
|
||||
|
||||
- Push-Location .\build-vc-64\newview\Release\
|
||||
- $FileNameWin64 = Get-ChildItem -Path . -Name -Include Singularity_*_Setup.exe
|
||||
- Invoke-WebRequest @UploadParams -InFile .\$FileNameWin64 -Uri "${UploadDestURL}/${FileNameWin64}"
|
||||
- Pop-Location
|
||||
|
||||
- sentry-cli releases new $BuildChannelVersion
|
||||
- sentry-cli releases set-commits --auto $BuildChannelVersion
|
||||
- sentry-cli releases finalize $BuildChannelVersion
|
||||
when: manual
|
||||
|
||||
deploy_project:
|
||||
<<: *deploy_template
|
||||
environment:
|
||||
name: qa
|
||||
only:
|
||||
- /^project-.*$/
|
||||
|
||||
deploy_beta:
|
||||
<<: *deploy_template
|
||||
environment:
|
||||
name: staging
|
||||
<<: *beta_rules
|
||||
|
||||
deploy_release:
|
||||
<<: *deploy_template
|
||||
environment:
|
||||
name: production
|
||||
<<: *release_rules
|
||||
301
autobuild.xml
301
autobuild.xml
@@ -47,40 +47,6 @@
|
||||
<key>version</key>
|
||||
<string>1.2.15</string>
|
||||
</map>
|
||||
<key>abseil-cpp</key>
|
||||
<map>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/alchemyviewer/3p-abseil-src</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright 2018 The Abseil Authors.</string>
|
||||
<key>description</key>
|
||||
<string>Abseil Common Libraries</string>
|
||||
<key>license</key>
|
||||
<string>Apache 2.0</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/abseil-cpp.txt</string>
|
||||
<key>name</key>
|
||||
<string>abseil-cpp</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>common</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b82d5aa8380926240f3415279480c831</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/abseil-cpp/common/abseil_cpp-ac78ffc.1-common-1.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>ac78ffc.1</string>
|
||||
</map>
|
||||
<key>apr_suite</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
@@ -423,6 +389,54 @@
|
||||
<key>version</key>
|
||||
<string>2.3</string>
|
||||
</map>
|
||||
<key>crashpad</key>
|
||||
<map>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://git.alchemyviewer.org/alchemy/thirdparty/3p-crashpad</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright 2014 The Crashpad Authors. All rights reserved.</string>
|
||||
<key>description</key>
|
||||
<string>Crashpad is a crash-reporting system.</string>
|
||||
<key>license</key>
|
||||
<string>Apache 2.0</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/crashpad.txt</string>
|
||||
<key>name</key>
|
||||
<string>crashpad</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4614b29cc98021cf1770a8290171602b</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows/crashpad-ce32d093.7-windows-7.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>d801461b7a6a40fffab828aa1e01e3e6</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows64/crashpad-ce32d093.7-windows64-7.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>ce32d093.7</string>
|
||||
</map>
|
||||
<key>curl</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
@@ -860,11 +874,11 @@
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>54dbd41322a08a1fc333ca6d96af5502</string>
|
||||
<string>ccd495598894c8e2e541a348015ee3f0</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>/opt/devel/secondlife/pkg/fmodstudio-2.00.02.191991250-linux64-191991250.tar.bz2</string>
|
||||
<string>/opt/devel/fmodstudio-2.00.07.200182252-linux64-200182252.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
@@ -874,11 +888,11 @@
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e0e87e0423fa42e4d2997b47b92eac6e</string>
|
||||
<string>22daed7c860daaef217eb8d90dfc1119</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.00.03.192211030-windows-192211030.tar.bz2</string>
|
||||
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.00.06.3-windows-3.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
@@ -888,62 +902,18 @@
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c2e55e1bfef7e066a0e40867a64b4cce</string>
|
||||
<string>ccf7b1935743df55244139c4323c0465</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.00.03.192211029-windows64-192211029.tar.bz2</string>
|
||||
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.00.06.3-windows64-3.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.10.10.190360453</string>
|
||||
</map>
|
||||
<key>fontconfig</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Šegan, 2012 Google, Inc.</string>
|
||||
<key>description</key>
|
||||
<string>Fontconfig is a library for configuring and customizing font access.</string>
|
||||
<key>license</key>
|
||||
<string>bsd</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/fontconfig.txt</string>
|
||||
<key>name</key>
|
||||
<string>fontconfig</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>linux</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>2843c48e6c84a51e3d6aa05dace4c8c0</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3pl_3p-fontconfig-update/rev/290569/arch/Linux/installer/fontconfig-2.11.0-linux-20140602.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>25726244f5bcd05f412514b030098c3c</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>http://depot.alchemyviewer.org/pub/linux64/lib-trusty/fontconfig-2.11.0-linux64-201603241804.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>2.11.0</string>
|
||||
<string>2.00.06.3</string>
|
||||
</map>
|
||||
<key>fonts</key>
|
||||
<map>
|
||||
@@ -1051,32 +1021,6 @@
|
||||
<key>name</key>
|
||||
<string>darwin</string>
|
||||
</map>
|
||||
<key>linux</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>52f87a65cc61ec4b05721c079d015b19</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3pl_3p-freetype-update/rev/290557/arch/Linux/installer/freetype-2.4.4-linux-20140602.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b10ba0775b9f1033daf580a2cb55789d</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>http://depot.alchemyviewer.org/pub/linux64/lib-trusty/freetype-2.6.3-linux64-201603241755.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
@@ -1271,104 +1215,6 @@
|
||||
<key>version</key>
|
||||
<string>1.0pre3.190390340</string>
|
||||
</map>
|
||||
<key>google_breakpad</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2006, Google Inc.</string>
|
||||
<key>description</key>
|
||||
<string>Breakpad is a crossplatform library for capturing crash callstacks and runtime data.</string>
|
||||
<key>license</key>
|
||||
<string>bsd</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/google_breakpad.txt</string>
|
||||
<key>name</key>
|
||||
<string>google_breakpad</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9f963eb1728e6d5077d4feba805d4896</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://bitbucket.org/alchemyviewer/publiclibs-darwin/downloads/google_breakpad-9e60a27-darwin-201511222009.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin</string>
|
||||
</map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>2d43c6a149cd9c89ba19e884579b1e25</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1836/4096/google_breakpad-1413.501824-darwin64-501824.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>52257e5eb166a0b69c9c0c38f6e1920e</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273079/arch/Linux/installer/google_breakpad-0.0.0-rev1099-linux-20130329.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>3709a51d4d5dff5ec0c4656623eaa05d</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>http://depot.alchemyviewer.org/pub/linux64/lib-trusty/google_breakpad-9e60a27-linux64-201603240004.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>fa7f683ba4ddd7db777c78c8213d2e46</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://depot.alchemyviewer.org/pub/windows/lib-vc141/google_breakpad-7398ce15b79da-windows-201703090621.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>71ffc5cae4da7e2e7aac856da44cb8c4</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://depot.alchemyviewer.org/pub/windows64/lib-vc141/google_breakpad-7398ce15b79da-windows64-201703081616.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>9e60a27</string>
|
||||
</map>
|
||||
<key>gperftools</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
@@ -2925,7 +2771,7 @@
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo</string>
|
||||
<string>-DWORD_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string>
|
||||
<string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string>
|
||||
<string>-DROOT_PROJECT_NAME:STRING=Singularity</string>
|
||||
<string>-DINSTALL_PROPRIETARY=FALSE</string>
|
||||
</array>
|
||||
@@ -2946,7 +2792,7 @@
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-DCMAKE_BUILD_TYPE:STRING=Release</string>
|
||||
<string>-DWORD_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string>
|
||||
<string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string>
|
||||
<string>-DROOT_PROJECT_NAME:STRING=Singularity</string>
|
||||
<string>-DINSTALL_PROPRIETARY=FALSE</string>
|
||||
</array>
|
||||
@@ -3029,10 +2875,10 @@
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>make</string>
|
||||
<string>ninja</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-j 7</string>
|
||||
<string>-v</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
@@ -3040,7 +2886,7 @@
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-G</string>
|
||||
<string>Unix Makefiles</string>
|
||||
<string>Ninja</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>default</key>
|
||||
@@ -3053,10 +2899,10 @@
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>make</string>
|
||||
<string>ninja</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-j 7</string>
|
||||
<string>-v</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
@@ -3064,7 +2910,7 @@
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-G</string>
|
||||
<string>Unix Makefiles</string>
|
||||
<string>Ninja</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
@@ -3085,10 +2931,10 @@
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>make</string>
|
||||
<string>ninja</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-j 7</string>
|
||||
<string>-v</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
@@ -3096,8 +2942,8 @@
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-G</string>
|
||||
<string>Unix Makefiles</string>
|
||||
<string>-DWORD_SIZE:STRING=64</string>
|
||||
<string>Ninja</string>
|
||||
<string>-DADDRESS_SIZE:STRING=64</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>default</key>
|
||||
@@ -3110,10 +2956,10 @@
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>make</string>
|
||||
<string>ninja</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-j 7</string>
|
||||
<string>-v</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
@@ -3121,8 +2967,8 @@
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-G</string>
|
||||
<string>Unix Makefiles</string>
|
||||
<string>-DWORD_SIZE:STRING=64</string>
|
||||
<string>Ninja</string>
|
||||
<string>-DADDRESS_SIZE:STRING=64</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
@@ -3135,7 +2981,7 @@
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>build_directory</key>
|
||||
<string>build-vc${AUTOBUILD_WIN_VSVER|161}-$AUTOBUILD_ADDRSIZE</string>
|
||||
<string>build-vc-$AUTOBUILD_ADDRSIZE</string>
|
||||
<key>configurations</key>
|
||||
<map>
|
||||
<key>RelWithDebInfo</key>
|
||||
@@ -3194,6 +3040,7 @@
|
||||
<string>/p:Configuration=Release</string>
|
||||
<string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
|
||||
<string>/t:Build</string>
|
||||
<string>/p:PreferredToolArchitecture=x64</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:normal</string>
|
||||
<string>/m</string>
|
||||
@@ -3221,7 +3068,7 @@
|
||||
</map>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version_file</key>
|
||||
|
||||
@@ -3,12 +3,7 @@
|
||||
# cmake_minimum_required should appear before any
|
||||
# other commands to guarantee full compatibility
|
||||
# with the version specified
|
||||
## prior to 2.8, the add_custom_target commands used in setting the version did not work correctly
|
||||
if(WIN32)
|
||||
cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
|
||||
else()
|
||||
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
|
||||
|
||||
set(ROOT_PROJECT_NAME "Singularity" CACHE STRING
|
||||
"The root project/makefile/solution name. Defaults to Singularity.")
|
||||
@@ -16,10 +11,6 @@ project(${ROOT_PROJECT_NAME})
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
include(Variables)
|
||||
include(00-Common)
|
||||
include(BuildVersion)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
@@ -28,9 +19,13 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||
"Build type. One of: Debug Release RelWithDebInfo" FORCE)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
include(Abseil-CPP)
|
||||
# Dependencies
|
||||
add_subdirectory(${ABSEIL_SRC_DIR} ${ABSEIL_BIN_DIR})
|
||||
include(Variables)
|
||||
include(00-Common)
|
||||
include(BuildVersion)
|
||||
include(CTest)
|
||||
|
||||
add_subdirectory(deps)
|
||||
|
||||
add_subdirectory(cmake)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}aistatemachine)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
|
||||
@@ -65,8 +60,10 @@ add_subdirectory(${LIBS_OPEN_PREFIX}plugins)
|
||||
|
||||
add_subdirectory(${VIEWER_PREFIX}newview/statemachine)
|
||||
add_subdirectory(${VIEWER_PREFIX}newview)
|
||||
add_dependencies(viewer ${VIEWER_BRANDING_ID}-bin)
|
||||
add_dependencies(viewer ${VIEWER_BINARY_NAME})
|
||||
|
||||
|
||||
if (WINDOWS)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${VIEWER_BRANDING_ID}-bin)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PROPERTY VS_STARTUP_PROJECT ${VIEWER_BINARY_NAME})
|
||||
endif (WINDOWS)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||
set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(Variables)
|
||||
|
||||
# Portable compilation flags.
|
||||
@@ -17,19 +18,6 @@ set(CMAKE_C_FLAGS_RELEASE
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"-DLL_RELEASE=1 -D_SECURE_SCL=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
|
||||
|
||||
# Configure crash reporting
|
||||
set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
|
||||
set(NON_RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in developer builds")
|
||||
|
||||
if(RELEASE_CRASH_REPORTING)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DLL_SEND_CRASH_REPORTS=1")
|
||||
endif()
|
||||
|
||||
if(NON_RELEASE_CRASH_REPORTING)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DLL_SEND_CRASH_REPORTS=1")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLL_SEND_CRASH_REPORTS=1")
|
||||
endif()
|
||||
|
||||
# Don't bother with a MinSizeRel build.
|
||||
set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING
|
||||
"Supported build types." FORCE)
|
||||
@@ -51,9 +39,17 @@ if (WINDOWS)
|
||||
"${CMAKE_C_FLAGS_RELEASE} ${LL_C_FLAGS} /O2 /Zi /MD /MP /fp:fast"
|
||||
CACHE STRING "C compiler release options" FORCE)
|
||||
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
if (FULL_DEBUG_SYMS OR USE_CRASHPAD)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG:FULL")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG:FULL")
|
||||
else ()
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG:FASTLINK")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG:FASTLINK")
|
||||
endif ()
|
||||
|
||||
if (USE_LTO)
|
||||
if(INCREMENTAL_LINK)
|
||||
@@ -107,9 +103,9 @@ if (WINDOWS)
|
||||
)
|
||||
endif (USE_LTO)
|
||||
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
add_compile_options(/arch:SSE2)
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
if (NOT DISABLE_FATAL_WARNINGS)
|
||||
add_definitions(/WX)
|
||||
@@ -199,10 +195,13 @@ if (LINUX)
|
||||
|
||||
# End of hacks.
|
||||
|
||||
if (NOT STANDALONE)
|
||||
# this stops us requiring a really recent glibc at runtime
|
||||
add_definitions(-fno-stack-protector)
|
||||
endif (NOT STANDALONE)
|
||||
CHECK_C_COMPILER_FLAG(-fstack-protector-strong HAS_STRONG_STACK_PROTECTOR)
|
||||
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
|
||||
if(HAS_STRONG_STACK_PROTECTOR)
|
||||
add_compile_options(-fstack-protector-strong)
|
||||
endif(HAS_STRONG_STACK_PROTECTOR)
|
||||
endif (${CMAKE_BUILD_TYPE} STREQUAL "Release")
|
||||
|
||||
if (${ARCH} STREQUAL "x86_64")
|
||||
add_definitions(-pipe)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math")
|
||||
@@ -293,19 +292,26 @@ if (LINUX OR DARWIN)
|
||||
|
||||
set(CMAKE_C_FLAGS "${UNIX_WARNINGS} ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${UNIX_CXX_WARNINGS} ${CMAKE_CXX_FLAGS}")
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
|
||||
elseif (WORD_SIZE EQUAL 64)
|
||||
elseif (ADDRESS_SIZE EQUAL 64)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64")
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
endif (LINUX OR DARWIN)
|
||||
|
||||
|
||||
if (STANDALONE)
|
||||
add_definitions(-DLL_STANDALONE=1)
|
||||
else (STANDALONE)
|
||||
#Enforce compile-time correctness for fmt strings
|
||||
add_definitions(-DFMT_STRING_ALIAS=1)
|
||||
|
||||
if(USE_CRASHPAD)
|
||||
add_definitions(-DUSE_CRASHPAD=1 -DCRASHPAD_URL="${CRASHPAD_URL}")
|
||||
endif()
|
||||
|
||||
set(${ARCH}_linux_INCLUDES
|
||||
atk-1.0
|
||||
cairo
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
set(BUILD_TESTING OFF)
|
||||
use_prebuilt_binary(abseil-cpp)
|
||||
set(ABSEIL_SRC_DIR ${LIBS_PREBUILT_DIR}/abseil-cpp)
|
||||
set(ABSEIL_BIN_DIR ${CMAKE_BINARY_DIR}/abseil-cpp)
|
||||
|
||||
@@ -9,7 +9,7 @@ include(Variables)
|
||||
# building in an IDE, it probably isn't. Set it explicitly using
|
||||
# run_build_test.py.
|
||||
add_custom_command(OUTPUT packages-info.txt
|
||||
COMMENT Generating packages-info.txt for the about box
|
||||
COMMENT "Generating packages-info.txt for the about box"
|
||||
MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/../autobuild.xml
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py
|
||||
${CMAKE_SOURCE_DIR}/../autobuild.xml
|
||||
|
||||
@@ -8,7 +8,6 @@ set(cmake_SOURCE_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
00-Common.cmake
|
||||
Abseil-CPP.cmake
|
||||
AIStateMachine.cmake
|
||||
APR.cmake
|
||||
Audio.cmake
|
||||
@@ -23,6 +22,7 @@ set(cmake_SOURCE_FILES
|
||||
ConfigurePkgConfig.cmake
|
||||
CURL.cmake
|
||||
Copy3rdPartyLibs.cmake
|
||||
CrashPad.cmake
|
||||
Cwdebug.cmake
|
||||
DBusGlib.cmake
|
||||
DeploySharedLibs.cmake
|
||||
@@ -33,7 +33,6 @@ set(cmake_SOURCE_FILES
|
||||
FindCARes.cmake
|
||||
FindColladadom.cmake
|
||||
FindGLOD.cmake
|
||||
FindGoogleBreakpad.cmake
|
||||
FindGooglePerfTools.cmake
|
||||
FindHunSpell.cmake
|
||||
FindNDOF.cmake
|
||||
@@ -43,11 +42,11 @@ set(cmake_SOURCE_FILES
|
||||
FindXmlRpcEpi.cmake
|
||||
FMODSTUDIO.cmake
|
||||
FreeType.cmake
|
||||
GeneratePrecompiledHeader.cmake
|
||||
GLOD.cmake
|
||||
GStreamer010Plugin.cmake
|
||||
Glui.cmake
|
||||
Glut.cmake
|
||||
GoogleBreakpad.cmake
|
||||
GooglePerfTools.cmake
|
||||
Hunspell.cmake
|
||||
JPEG.cmake
|
||||
|
||||
@@ -6,17 +6,17 @@ SET(DEBUG_PKG_CONFIG "YES")
|
||||
IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
|
||||
|
||||
# Guess at architecture-specific system library paths.
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib)
|
||||
SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib)
|
||||
SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu)
|
||||
SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu)
|
||||
else (WORD_SIZE EQUAL 32)
|
||||
else (ADDRESS_SIZE EQUAL 32)
|
||||
SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib)
|
||||
SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib)
|
||||
SET(PKG_CONFIG_MULTI_GUESS /usr/lib/x86_64-linux-gnu)
|
||||
SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu)
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
# Use DPKG architecture, if available.
|
||||
IF (${DPKG_ARCH})
|
||||
|
||||
@@ -82,14 +82,19 @@ if(WINDOWS)
|
||||
endif(ADDRESS_SIZE EQUAL 64)
|
||||
|
||||
if(NOT DISABLE_TCMALLOC)
|
||||
set(debug_files ${debug_files} libtcmalloc_minimal-debug.dll)
|
||||
set(release_files ${release_files} libtcmalloc_minimal.dll)
|
||||
list(APPEND debug_files libtcmalloc_minimal-debug.dll)
|
||||
list(APPEND release_files libtcmalloc_minimal.dll)
|
||||
endif(NOT DISABLE_TCMALLOC)
|
||||
|
||||
if (FMODSTUDIO)
|
||||
set(debug_files ${debug_files} fmodL.dll)
|
||||
set(release_files ${release_files} fmod.dll)
|
||||
endif (FMODSTUDIO)
|
||||
if(OPENAL)
|
||||
list(APPEND debug_files alut.dll OpenAL32.dll)
|
||||
list(APPEND release_files alut.dll OpenAL32.dll)
|
||||
endif(OPENAL)
|
||||
|
||||
if (USE_FMODSTUDIO)
|
||||
list(APPEND debug_files fmodL.dll)
|
||||
list(APPEND release_files fmod.dll)
|
||||
endif (USE_FMODSTUDIO)
|
||||
|
||||
foreach(redistfullfile IN LISTS CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
|
||||
get_filename_component(redistfilepath ${redistfullfile} DIRECTORY )
|
||||
@@ -179,26 +184,20 @@ elseif(LINUX)
|
||||
libatk-1.0.so
|
||||
libexpat.so
|
||||
libexpat.so.1
|
||||
libfreetype.so.6.12.3
|
||||
libfreetype.so.6
|
||||
libfreetype.so
|
||||
libGLOD.so
|
||||
libgmodule-2.0.so
|
||||
libgobject-2.0.so
|
||||
libopenal.so
|
||||
libfontconfig.so.1.8.0
|
||||
libfontconfig.so.1
|
||||
libfontconfig.so
|
||||
)
|
||||
|
||||
if (USE_TCMALLOC)
|
||||
set(release_files ${release_files} "libtcmalloc_minimal.so")
|
||||
list(APPEND release_files "libtcmalloc_minimal.so")
|
||||
endif (USE_TCMALLOC)
|
||||
|
||||
if (FMODSTUDIO)
|
||||
set(debug_files ${debug_files} "libfmodL.so")
|
||||
set(release_files ${release_files} "libfmod.so")
|
||||
endif (FMODSTUDIO)
|
||||
if (USE_FMODSTUDIO)
|
||||
list(APPEND debug_files "libfmodL.so")
|
||||
list(APPEND release_files "libfmod.so")
|
||||
endif (USE_FMODSTUDIO)
|
||||
|
||||
else(WINDOWS)
|
||||
message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...")
|
||||
|
||||
22
indra/cmake/CrashPad.cmake
Normal file
22
indra/cmake/CrashPad.cmake
Normal file
@@ -0,0 +1,22 @@
|
||||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
include(Variables)
|
||||
|
||||
if(USE_CRASHPAD)
|
||||
|
||||
if (USESYSTEMLIBS)
|
||||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(crashpad)
|
||||
if (WINDOWS)
|
||||
set(CRASHPAD_LIBRARIES
|
||||
debug client.lib util.lib base.lib
|
||||
optimized client.lib util.lib base.lib)
|
||||
elseif (LINUX)
|
||||
|
||||
else (DARWIN)
|
||||
|
||||
endif ()
|
||||
set(CRASHPAD_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/crashpad)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
||||
endif()
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
include(Variables)
|
||||
if (FMODSTUDIO)
|
||||
if (USE_FMODSTUDIO)
|
||||
use_prebuilt_binary(fmodstudio)
|
||||
if(WINDOWS)
|
||||
set(lib_suffix .dll)
|
||||
@@ -30,22 +30,21 @@ if (FMODSTUDIO)
|
||||
optimized ${FMOD_LINK_LIBRARY_RELEASE}
|
||||
)
|
||||
|
||||
set(FMOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio)
|
||||
endif(FMODSTUDIO)
|
||||
set(FMODSTUDIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio)
|
||||
endif(USE_FMODSTUDIO)
|
||||
|
||||
if(FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
|
||||
if(FMOD_LIBRARY_RELEASE AND FMODSTUDIO_INCLUDE_DIR)
|
||||
set(FMOD ON)
|
||||
if (NOT FMOD_LIBRARY_DEBUG) #Use release library in debug configuration if debug library is absent.
|
||||
set(FMOD_LIBRARY_DEBUG ${FMOD_LIBRARY_RELEASE})
|
||||
endif (NOT FMOD_LIBRARY_DEBUG)
|
||||
else (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
|
||||
else (FMOD_LIBRARY_RELEASE AND FMODSTUDIO_INCLUDE_DIR)
|
||||
message(STATUS "No support for FMOD Studio audio (need to set FMODSTUDIO_SDK_DIR?)")
|
||||
set(FMOD OFF)
|
||||
set(FMODSTUDIO OFF)
|
||||
endif (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
|
||||
set(USE_FMODSTUDIO OFF)
|
||||
endif (FMOD_LIBRARY_RELEASE AND FMODSTUDIO_INCLUDE_DIR)
|
||||
|
||||
if (FMOD)
|
||||
message(STATUS "Building with FMOD Studio audio support")
|
||||
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO=1")
|
||||
endif (FMOD)
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
# - Find Google BreakPad
|
||||
# Find the Google BreakPad includes and library
|
||||
# This module defines
|
||||
# BREAKPAD_INCLUDE_DIRECTORIES, where to find the Goole BreakPad includes.
|
||||
# BREAKPAD_EXCEPTION_HANDLER_LIBRARIES, the libraries needed to use Google BreakPad.
|
||||
# BREAKPAD_EXCEPTION_HANDLER_FOUND, If false, do not try to use Google BreakPad.
|
||||
# also defined, but not for general use are
|
||||
# BREAKPAD_EXCEPTION_HANDLER_LIBRARY, where to find the Google BreakPad library.
|
||||
|
||||
FIND_PATH(BREAKPAD_INCLUDE_DIRECTORIES common/using_std_string.h PATH_SUFFIXES google_breakpad)
|
||||
|
||||
SET(BREAKPAD_EXCEPTION_HANDLER_NAMES ${BREAKPAD_EXCEPTION_HANDLER_NAMES} breakpad_client)
|
||||
FIND_LIBRARY(BREAKPAD_EXCEPTION_HANDLER_LIBRARY
|
||||
NAMES ${BREAKPAD_EXCEPTION_HANDLER_NAMES}
|
||||
)
|
||||
|
||||
IF (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_INCLUDE_DIRECTORIES)
|
||||
SET(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES ${BREAKPAD_EXCEPTION_HANDLER_LIBRARY})
|
||||
SET(BREAKPAD_EXCEPTION_HANDLER_FOUND "YES")
|
||||
ELSE (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_INCLUDE_DIRECTORIES)
|
||||
SET(BREAKPAD_EXCEPTION_HANDLER_FOUND "NO")
|
||||
ENDIF (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_INCLUDE_DIRECTORIES)
|
||||
|
||||
|
||||
IF (BREAKPAD_EXCEPTION_HANDLER_FOUND)
|
||||
IF (NOT BREAKPAD_EXCEPTION_HANDLER_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found Google BreakPad: ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}")
|
||||
ENDIF (NOT BREAKPAD_EXCEPTION_HANDLER_FIND_QUIETLY)
|
||||
ELSE (BREAKPAD_EXCEPTION_HANDLER_FOUND)
|
||||
IF (BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find Google BreakPad library")
|
||||
ENDIF (BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED)
|
||||
ENDIF (BREAKPAD_EXCEPTION_HANDLER_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
BREAKPAD_EXCEPTION_HANDLER_LIBRARY
|
||||
BREAKPAD_INCLUDE_DIRECTORIES
|
||||
)
|
||||
@@ -1,14 +1,14 @@
|
||||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
if (STANDALONE)
|
||||
if (LINUX)
|
||||
include(FindPkgConfig)
|
||||
|
||||
pkg_check_modules(FREETYPE REQUIRED freetype2)
|
||||
else (STANDALONE)
|
||||
else (LINUX)
|
||||
use_prebuilt_binary(freetype)
|
||||
set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/freetype2)
|
||||
set(FREETYPE_LIBRARIES freetype)
|
||||
endif (STANDALONE)
|
||||
endif (LINUX)
|
||||
|
||||
link_directories(${FREETYPE_LIBRARY_DIRS})
|
||||
|
||||
116
indra/cmake/GeneratePrecompiledHeader.cmake
Normal file
116
indra/cmake/GeneratePrecompiledHeader.cmake
Normal file
@@ -0,0 +1,116 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
# Distributed under the MIT Software License
|
||||
# Copyright (c) 2015-2017 Borislav Stanimirov
|
||||
# Modifications Copyright (c) 2019 Cinder Roxley. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
# of the Software, and to permit persons to whom the Software is furnished to do
|
||||
# so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
# target_precompiled_header
|
||||
#
|
||||
# Sets a precompiled header for a given target
|
||||
# Args:
|
||||
# TARGET_NAME - Name of the target. Only valid after add_library or add_executable
|
||||
# PRECOMPILED_HEADER - Header file to precompile
|
||||
# PRECOMPILED_SOURCE - MSVC specific source to do the actual precompilation. Ignored on other platforms
|
||||
#
|
||||
|
||||
macro(target_precompiled_header TARGET_NAME PRECOMPILED_HEADER PRECOMPILED_SOURCE)
|
||||
get_filename_component(PRECOMPILED_HEADER_NAME ${PRECOMPILED_HEADER} NAME)
|
||||
|
||||
if(MSVC)
|
||||
get_filename_component(PRECOMPILED_SOURCE_NAME ${PRECOMPILED_SOURCE} NAME)
|
||||
get_filename_component(PRECOMPILED_HEADER_PATH ${PRECOMPILED_HEADER} DIRECTORY)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${PRECOMPILED_HEADER_PATH}) # fixes occasional IntelliSense glitches
|
||||
|
||||
get_filename_component(PRECOMPILED_HEADER_WE ${PRECOMPILED_HEADER} NAME_WE)
|
||||
if(GEN_IS_MULTI_CONFIG)
|
||||
set(PRECOMPILED_BINARY "$(IntDir)/${PRECOMPILED_HEADER_WE}.pch")
|
||||
else()
|
||||
set(PRECOMPILED_BINARY "${CMAKE_CURRENT_BINARY_DIR}/${PRECOMPILED_HEADER_WE}.pch")
|
||||
endif()
|
||||
|
||||
set_source_files_properties(${PRECOMPILED_SOURCE} PROPERTIES
|
||||
COMPILE_OPTIONS "/Yc${PRECOMPILED_HEADER_NAME};/Fp${PRECOMPILED_BINARY}"
|
||||
OBJECT_OUTPUTS "${PRECOMPILED_BINARY}")
|
||||
|
||||
get_target_property(TARGET_SOURCES ${TARGET_NAME} SOURCES)
|
||||
foreach(src ${TARGET_SOURCES})
|
||||
if(${src} MATCHES \\.\(cpp|cxx|cc\)$)
|
||||
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${src}" PROPERTIES
|
||||
COMPILE_OPTIONS "/Yu${PRECOMPILED_HEADER_NAME};/FI${PRECOMPILED_HEADER_NAME};/Fp${PRECOMPILED_BINARY}"
|
||||
OBJECT_DEPENDS "${PRECOMPILED_BINARY}"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
#set_target_properties(${TARGET_NAME} PROPERTIES
|
||||
# COMPILE_OPTIONS "/Yu${PRECOMPILED_HEADER_NAME};/FI${PRECOMPILED_HEADER_NAME};/Fp${PRECOMPILED_BINARY}")
|
||||
|
||||
target_sources(${TARGET_NAME} PRIVATE ${PRECOMPILED_SOURCE} ${PRECOMPILED_HEADER})
|
||||
elseif(CMAKE_GENERATOR STREQUAL Xcode)
|
||||
set_target_properties(
|
||||
${TARGET_NAME}
|
||||
PROPERTIES
|
||||
XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${PRECOMPILED_HEADER}"
|
||||
XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES"
|
||||
)
|
||||
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# Create and set output directory.
|
||||
set(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${PRECOMPILED_HEADER_NAME}.gch")
|
||||
make_directory(${OUTPUT_DIR})
|
||||
set(OUTPUT_NAME "${OUTPUT_DIR}/${PRECOMPILED_HEADER_NAME}.gch")
|
||||
|
||||
# Export compiler flags via a generator to a response file
|
||||
set(PCH_FLAGS_FILE "${OUTPUT_DIR}/${PRECOMPILED_HEADER_NAME}.rsp")
|
||||
set(_include_directories "$<TARGET_PROPERTY:${TARGET_NAME},INCLUDE_DIRECTORIES>")
|
||||
set(_compile_definitions "$<TARGET_PROPERTY:${TARGET_NAME},COMPILE_DEFINITIONS>")
|
||||
set(_compile_flags "$<TARGET_PROPERTY:${TARGET_NAME},COMPILE_FLAGS>")
|
||||
set(_compile_options "$<TARGET_PROPERTY:${TARGET_NAME},COMPILE_OPTIONS>")
|
||||
set(_include_directories "$<$<BOOL:${_include_directories}>:-I$<JOIN:${_include_directories},\n-I>\n>")
|
||||
set(_compile_definitions "$<$<BOOL:${_compile_definitions}>:-D$<JOIN:${_compile_definitions},\n-D>\n>")
|
||||
set(_compile_flags "$<$<BOOL:${_compile_flags}>:$<JOIN:${_compile_flags},\n>\n>")
|
||||
set(_compile_options "$<$<BOOL:${_compile_options}>:$<JOIN:${_compile_options},\n>\n>")
|
||||
file(GENERATE OUTPUT "${PCH_FLAGS_FILE}" CONTENT "${_compile_definitions}${_include_directories}${_compile_flags}${_compile_options}\n")
|
||||
|
||||
# Gather global compiler options, definitions, etc.
|
||||
string(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" CXX_FLAGS)
|
||||
set(COMPILER_FLAGS "${${CXX_FLAGS}} ${CMAKE_CXX_FLAGS}")
|
||||
separate_arguments(COMPILER_FLAGS)
|
||||
|
||||
# Add a custom target for building the precompiled header.
|
||||
add_custom_command(
|
||||
OUTPUT ${OUTPUT_NAME}
|
||||
COMMAND ${CMAKE_CXX_COMPILER} @${PCH_FLAGS_FILE} ${COMPILER_FLAGS} -x c++-header -o ${OUTPUT_NAME} ${PRECOMPILED_HEADER}
|
||||
DEPENDS ${PRECOMPILED_HEADER})
|
||||
add_custom_target(${TARGET_NAME}_gch DEPENDS ${OUTPUT_NAME})
|
||||
add_dependencies(${TARGET_NAME} ${TARGET_NAME}_gch)
|
||||
|
||||
# set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_FLAGS "-include ${PRECOMPILED_HEADER_NAME} -Winvalid-pch")
|
||||
get_target_property(SOURCE_FILES ${TARGET_NAME} SOURCES)
|
||||
get_target_property(asdf ${TARGET_NAME} COMPILE_FLAGS)
|
||||
foreach(SOURCE_FILE ${SOURCE_FILES})
|
||||
if(SOURCE_FILE MATCHES \\.\(c|cc|cxx|cpp\)$)
|
||||
set_source_files_properties(${SOURCE_FILE} PROPERTIES
|
||||
COMPILE_FLAGS "-include ${OUTPUT_DIR}/${PRECOMPILED_HEADER_NAME} -Winvalid-pch"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown generator for target_precompiled_header. [${CMAKE_CXX_COMPILER_ID}]")
|
||||
endif()
|
||||
endmacro(target_precompiled_header)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
if (STANDALONE)
|
||||
set(BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED ON)
|
||||
include(FindGoogleBreakpad)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(google_breakpad)
|
||||
if (DARWIN)
|
||||
set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler)
|
||||
endif (DARWIN)
|
||||
if (LINUX)
|
||||
set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES breakpad_client)
|
||||
endif (LINUX)
|
||||
if (WINDOWS)
|
||||
set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler crash_generation_client crash_generation_server common)
|
||||
endif (WINDOWS)
|
||||
# yes, this does look dumb, no, it's not incorrect
|
||||
# I think it's incorrect: the second one should go --Aleric
|
||||
set(BREAKPAD_INCLUDE_DIRECTORIES
|
||||
${LIBS_PREBUILT_DIR}/include/google_breakpad
|
||||
${LIBS_PREBUILT_LEGACY_DIR}/include/google_breakpad
|
||||
${LIBS_PREBUILT_DIR}/include/google_breakpad/google_breakpad
|
||||
${LIBS_PREBUILT_LEGACY_DIR}/include/google_breakpad/google_breakpad
|
||||
)
|
||||
endif (STANDALONE)
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
include(Prebuilt)
|
||||
|
||||
if(WORD_SIZE EQUAL 64)
|
||||
if(ADDRESS_SIZE EQUAL 64)
|
||||
set(DISABLE_TCMALLOC TRUE)
|
||||
endif(WORD_SIZE EQUAL 64)
|
||||
endif(ADDRESS_SIZE EQUAL 64)
|
||||
|
||||
if (STANDALONE)
|
||||
include(FindGooglePerfTools)
|
||||
else (STANDALONE)
|
||||
if (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
|
||||
if (LINUX OR WINDOWS AND NOT ADDRESS_SIZE EQUAL 64)
|
||||
use_prebuilt_binary(gperftools)
|
||||
endif (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
|
||||
endif (LINUX OR WINDOWS AND NOT ADDRESS_SIZE EQUAL 64)
|
||||
if (WINDOWS AND NOT DISABLE_TCMALLOC)
|
||||
set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib)
|
||||
set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"")
|
||||
|
||||
@@ -10,7 +10,6 @@ if (DARWIN)
|
||||
find_library(CORESERVICES_LIBRARY CoreServices)
|
||||
endif (DARWIN)
|
||||
|
||||
|
||||
set(LLCOMMON_INCLUDE_DIRS
|
||||
${LIBS_OPEN_DIR}/cwdebug
|
||||
${LIBS_OPEN_DIR}/llcommon
|
||||
@@ -19,14 +18,7 @@ set(LLCOMMON_INCLUDE_DIRS
|
||||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
# In order to support using ld.gold on linux, we need to explicitely
|
||||
# specify all libraries that llcommon uses.
|
||||
# llcommon uses `clock_gettime' which is provided by librt on linux.
|
||||
set(LLCOMMON_LIBRARIES llcommon rt)
|
||||
else (LINUX)
|
||||
set(LLCOMMON_LIBRARIES llcommon)
|
||||
endif (LINUX)
|
||||
set(LLCOMMON_LIBRARIES llcommon)
|
||||
|
||||
set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a shared library.")
|
||||
if(LLCOMMON_LINK_SHARED)
|
||||
|
||||
@@ -5,10 +5,4 @@ set(LLPLUGIN_INCLUDE_DIRS
|
||||
${LIBS_OPEN_DIR}/llplugin
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
# In order to support using ld.gold on linux, we need to explicitely
|
||||
# specify all libraries that llplugin uses.
|
||||
set(LLPLUGIN_LIBRARIES llplugin pthread)
|
||||
else (LINUX)
|
||||
set(LLPLUGIN_LIBRARIES llplugin)
|
||||
endif (LINUX)
|
||||
set(LLPLUGIN_LIBRARIES llplugin)
|
||||
|
||||
@@ -27,15 +27,15 @@ endif (WINDOWS)
|
||||
# windows) and CMAKE_BUILD_TYPE on Makefile based generators (like linux). The reason for this is
|
||||
# that CMAKE_BUILD_TYPE is essentially meaningless at configuration time for IDE generators and
|
||||
# CMAKE_CFG_INTDIR is meaningless at build time for Makefile generators
|
||||
if(WINDOWS OR DARWIN)
|
||||
if(GEN_IS_MULTI_CONFIG)
|
||||
# the cmake xcode and VS generators implicitly append ${CMAKE_CFG_INTDIR} to the library paths for us
|
||||
# fortunately both windows and darwin are case insensitive filesystems so this works.
|
||||
set(AUTOBUILD_LIBS_INSTALL_DIRS "${AUTOBUILD_INSTALL_DIR}/lib/")
|
||||
else(WINDOWS OR DARWIN)
|
||||
else()
|
||||
# else block is for linux and any other makefile based generators
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
|
||||
set(AUTOBUILD_LIBS_INSTALL_DIRS ${AUTOBUILD_INSTALL_DIR}/lib/${CMAKE_BUILD_TYPE_LOWER})
|
||||
endif(WINDOWS OR DARWIN)
|
||||
endif()
|
||||
|
||||
if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
||||
# When we're building something other than Release, append the
|
||||
@@ -48,10 +48,14 @@ link_directories(${AUTOBUILD_LIBS_INSTALL_DIRS})
|
||||
|
||||
if (LINUX)
|
||||
set(DL_LIBRARY dl)
|
||||
set(RT_LIBRARY rt)
|
||||
set(PTHREAD_LIBRARY pthread)
|
||||
set(FMT_LIBRARY "")
|
||||
else (LINUX)
|
||||
set(DL_LIBRARY "")
|
||||
set(RT_LIBRARY "")
|
||||
set(PTHREAD_LIBRARY "")
|
||||
set(FMT_LIBRARY fmt::fmt)
|
||||
endif (LINUX)
|
||||
|
||||
if (WINDOWS)
|
||||
@@ -73,6 +77,6 @@ else (WINDOWS)
|
||||
set(WINDOWS_LIBRARIES "")
|
||||
endif (WINDOWS)
|
||||
|
||||
mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES)
|
||||
mark_as_advanced(DL_LIBRARY RT_LIBRARY PTHREAD_LIBRARY FMT_LIBRARY WINDOWS_LIBRARIES)
|
||||
|
||||
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
include(Prebuilt)
|
||||
include(Variables)
|
||||
|
||||
if (NVAPI)
|
||||
if (USE_NVAPI)
|
||||
if (WINDOWS)
|
||||
use_prebuilt_binary(nvapi)
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
set(NVAPI_LIBRARY nvapi)
|
||||
elseif (WORD_SIZE EQUAL 64)
|
||||
elseif (ADDRESS_SIZE EQUAL 64)
|
||||
set(NVAPI_LIBRARY nvapi64)
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
else (WINDOWS)
|
||||
set(NVAPI_LIBRARY "")
|
||||
endif (WINDOWS)
|
||||
else (NVAPI)
|
||||
else (USE_NVAPI)
|
||||
set(NVAPI_LIBRARY "")
|
||||
endif (NVAPI)
|
||||
endif (USE_NVAPI)
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
include(Linking)
|
||||
include(Prebuilt)
|
||||
|
||||
if(NOT FMOD)
|
||||
if (LINUX)
|
||||
set(OPENAL ON CACHE BOOL "Enable OpenAL")
|
||||
else (LINUX)
|
||||
@@ -10,6 +9,7 @@ else (LINUX)
|
||||
endif (LINUX)
|
||||
|
||||
if (OPENAL)
|
||||
set(OPENAL_LIB_INCLUDE_DIRS "${LIBS_PREBUILT_DIR}/include/AL")
|
||||
if (STANDALONE)
|
||||
include(FindPkgConfig)
|
||||
include(FindOpenAL)
|
||||
@@ -18,15 +18,16 @@ if (OPENAL)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(openal)
|
||||
endif (STANDALONE)
|
||||
if(WINDOWS)
|
||||
set(OPENAL_LIBRARIES
|
||||
openal
|
||||
OpenAL32
|
||||
alut
|
||||
)
|
||||
set(OPENAL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (OPENAL)
|
||||
|
||||
if (OPENAL)
|
||||
else()
|
||||
set(OPENAL_LIBRARIES
|
||||
openal
|
||||
alut
|
||||
)
|
||||
endif()
|
||||
message(STATUS "Building with OpenAL audio support")
|
||||
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
|
||||
endif (OPENAL)
|
||||
endif(NOT FMOD)
|
||||
|
||||
@@ -17,24 +17,59 @@ if(NOT DEFINED COMMON_CMAKE_DIR)
|
||||
set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")
|
||||
endif(NOT DEFINED COMMON_CMAKE_DIR)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# https://blog.kitware.com/upcoming-in-cmake-2-8-12-osx-rpath-support/
|
||||
set(CMAKE_MACOSX_RPATH ON)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF)
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
option(GEN_IS_MULTI_CONFIG "" ${_isMultiConfig})
|
||||
mark_as_advanced(GEN_IS_MULTI_CONFIG)
|
||||
|
||||
set(LIBS_CLOSED_PREFIX)
|
||||
set(LIBS_OPEN_PREFIX)
|
||||
set(SCRIPTS_PREFIX ../scripts)
|
||||
set(VIEWER_PREFIX)
|
||||
set(INTEGRATION_TESTS_PREFIX)
|
||||
option(LL_TESTS "Build and run unit and integration tests (disable for build timing runs to reduce variation" OFF)
|
||||
|
||||
option(LL_TESTS "Build and run unit and integration tests (disable for build timing runs to reduce variation" OFF)
|
||||
option(BUILD_TESTING "Build test suite" OFF)
|
||||
option(UNATTENDED "Disable use of uneeded tooling for automated builds" OFF)
|
||||
|
||||
# Compiler and toolchain options
|
||||
option(USESYSTEMLIBS "Use libraries from your system rather than Linden-supplied prebuilt libraries." OFF)
|
||||
option(STANDALONE "Use libraries from your system rather than Linden-supplied prebuilt libraries." OFF)
|
||||
if (USESYSTEMLIBS)
|
||||
set(STANDALONE ON)
|
||||
elseif (STANDALONE)
|
||||
set(USESYSTEMLIBS ON)
|
||||
endif (USESYSTEMLIBS)
|
||||
option(INCREMENTAL_LINK "Use incremental linking on win32 builds (enable for faster links on some machines)" OFF)
|
||||
option(USE_PRECOMPILED_HEADERS "Enable use of precompiled header directives where supported." ON)
|
||||
option(USE_LTO "Enable Whole Program Optimization and related folding and binary reduction routines" OFF)
|
||||
option(UNATTENDED "Disable use of uneeded tooling for automated builds" OFF)
|
||||
option(USE_LTO "Enable global and interprocedural optimizations" OFF)
|
||||
|
||||
# Configure crash reporting
|
||||
option(USE_CRASHPAD "Build support for crashpad reporting engine" OFF)
|
||||
if (DEFINED ENV{VIEWER_USE_CRASHPAD})
|
||||
set(USE_CRASHPAD $ENV{VIEWER_USE_CRASHPAD})
|
||||
endif()
|
||||
|
||||
if (DEFINED ENV{VIEWER_CRASHPAD_URL})
|
||||
set(CRASHPAD_URL $ENV{VIEWER_CRASHPAD_URL} CACHE STRING "Viewer Channel Base Name")
|
||||
else()
|
||||
set(CRASHPAD_URL "" CACHE STRING "Crashpad endpoint url")
|
||||
endif()
|
||||
|
||||
set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files")
|
||||
|
||||
# Media Plugins
|
||||
option(ENABLE_MEDIA_PLUGINS "Turn off building media plugins if they are imported by third-party library mechanism" ON)
|
||||
option(LIBVLCPLUGIN "Turn off building support for libvlc plugin" ON)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(LIBVLCPLUGIN OFF)
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
@@ -44,13 +79,11 @@ set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds
|
||||
set(DISABLE_FATAL_WARNINGS TRUE CACHE BOOL "Set this to FALSE to enable fatal warnings.")
|
||||
|
||||
# Audio Engines
|
||||
option(FMODSTUDIO "Build with support for the FMOD Studio audio engine" ON)
|
||||
|
||||
# Window implementation
|
||||
option(LLWINDOW_SDL2 "Use SDL2 for window and input handling" OFF)
|
||||
option(USE_FMODSTUDIO "Build with support for the FMOD Studio audio engine" OFF)
|
||||
|
||||
# Proprietary Library Features
|
||||
option(NVAPI "Use nvapi driver interface library" OFF)
|
||||
option(USE_NVAPI "Use nvapi driver interface library" OFF)
|
||||
|
||||
|
||||
if(LIBS_CLOSED_DIR)
|
||||
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)
|
||||
@@ -77,7 +110,7 @@ if (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)
|
||||
set(INSTALL_PROPRIETARY ON CACHE BOOL "Install proprietary binaries")
|
||||
endif (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)
|
||||
set(TEMPLATE_VERIFIER_OPTIONS "" CACHE STRING "Options for scripts/template_verifier.py")
|
||||
set(TEMPLATE_VERIFIER_MASTER_URL "https://forge.alchemyviewer.org/alchemy/tools/Master-Message-Template/raw/master/message_template.msg" CACHE STRING "Location of the master message template")
|
||||
set(TEMPLATE_VERIFIER_MASTER_URL "https://git.alchemyviewer.org/alchemy/master-message-template/raw/master/message_template.msg" CACHE STRING "Location of the master message template")
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
|
||||
@@ -86,7 +119,6 @@ endif (NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# If someone has specified an address size, use that to determine the
|
||||
# architecture. Otherwise, let the architecture specify the address size.
|
||||
set(ADDRESS_SIZE ${WORD_SIZE})
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
#message(STATUS "ADDRESS_SIZE is 32")
|
||||
set(ARCH i686)
|
||||
@@ -94,34 +126,32 @@ elseif (ADDRESS_SIZE EQUAL 64)
|
||||
#message(STATUS "ADDRESS_SIZE is 64")
|
||||
set(ARCH x86_64)
|
||||
else (ADDRESS_SIZE EQUAL 32)
|
||||
#message(STATUS "ADDRESS_SIZE is UNRECOGNIZED: '${ADDRESS_SIZE}'")
|
||||
# Use Python's platform.machine() since uname -m isn't available everywhere.
|
||||
# Even if you can assume cygwin uname -m, the answer depends on whether
|
||||
# you're running 32-bit cygwin or 64-bit cygwin! But even 32-bit Python will
|
||||
# report a 64-bit processor.
|
||||
execute_process(COMMAND
|
||||
"${Python2_EXECUTABLE}" "-c"
|
||||
"import platform; print platform.machine()"
|
||||
OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
# We expect values of the form i386, i686, x86_64, AMD64.
|
||||
# In CMake, expressing ARCH.endswith('64') is awkward:
|
||||
string(LENGTH "${ARCH}" ARCH_LENGTH)
|
||||
math(EXPR ARCH_LEN_2 "${ARCH_LENGTH} - 2")
|
||||
string(SUBSTRING "${ARCH}" ${ARCH_LEN_2} 2 ARCH_LAST_2)
|
||||
if (ARCH_LAST_2 STREQUAL 64)
|
||||
#message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}")
|
||||
set(ADDRESS_SIZE 64)
|
||||
else()
|
||||
#message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}")
|
||||
set(ADDRESS_SIZE 32)
|
||||
endif ()
|
||||
#message(STATUS "ADDRESS_SIZE is UNDEFINED")
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
message(STATUS "Size of void pointer is detected as 8; ARCH is 64-bit")
|
||||
set(ARCH x86_64)
|
||||
set(ADDRESS_SIZE 64)
|
||||
elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
message(STATUS "Size of void pointer is detected as 4; ARCH is 32-bit")
|
||||
set(ADDRESS_SIZE 32)
|
||||
set(ARCH i686)
|
||||
else()
|
||||
message(FATAL_ERROR "Unkown Architecture!")
|
||||
endif()
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
set(WINDOWS ON BOOL FORCE)
|
||||
if (ADDRESS_SIZE EQUAL 64)
|
||||
set(LL_ARCH ${ARCH}_win64)
|
||||
set(LL_ARCH_DIR ${ARCH}-win64)
|
||||
elseif (ADDRESS_SIZE EQUAL 32)
|
||||
set(LL_ARCH ${ARCH}_win32)
|
||||
set(LL_ARCH_DIR ${ARCH}-win32)
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
else()
|
||||
message(FATAL_ERROR "Unkown Architecture!")
|
||||
endif ()
|
||||
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(LINUX ON BOOL FORCE)
|
||||
@@ -152,7 +182,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(DARWIN 1)
|
||||
set(DARWIN ON BOOL FORCE)
|
||||
|
||||
# Architecture
|
||||
set(CMAKE_OSX_SYSROOT macosx10.14)
|
||||
@@ -192,57 +222,60 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(LL_ARCH_DIR universal-darwin)
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
||||
# Platform specific
|
||||
if (WINDOWS)
|
||||
option(LLWINDOW_SDL2 "Use SDL2 for window and input handling. Windows only" OFF)
|
||||
endif()
|
||||
|
||||
# Default deploy grid
|
||||
set(GRID agni CACHE STRING "Target Grid")
|
||||
|
||||
set(VIEWER_PRODUCT_NAME "Singularity" CACHE STRING "Viewer Base Name")
|
||||
string(TOLOWER ${VIEWER_PRODUCT_NAME} VIEWER_PRODUCT_NAME_LOWER)
|
||||
if (DEFINED ENV{VIEWER_CHANNEL_BASE})
|
||||
set(VIEWER_CHANNEL_BASE $ENV{VIEWER_CHANNEL_BASE} CACHE STRING "Viewer Channel Base Name" FORCE)
|
||||
else()
|
||||
set(VIEWER_CHANNEL_BASE "Singularity" CACHE STRING "Viewer Channel Base Name")
|
||||
endif()
|
||||
|
||||
if (DEFINED ENV{VIEWER_CHANNEL_TYPE})
|
||||
set(VIEWER_CHANNEL_TYPE $ENV{VIEWER_CHANNEL_TYPE} CACHE STRING "Viewer Channel Type Name" FORCE)
|
||||
else()
|
||||
set(VIEWER_CHANNEL_TYPE "Test" CACHE STRING "Viewer Channel Type Name")
|
||||
endif()
|
||||
|
||||
if (DEFINED ENV{VIEWER_CHANNEL_CODENAME})
|
||||
set(VIEWER_CHANNEL_CODENAME $ENV{VIEWER_CHANNEL_CODENAME} CACHE STRING "Viewer Channel Code Name for Project type" FORCE)
|
||||
else()
|
||||
set(VIEWER_CHANNEL_CODENAME "Default" CACHE STRING "Viewer Channel Code Name for Project type")
|
||||
endif()
|
||||
|
||||
if("${VIEWER_CHANNEL_TYPE}" STREQUAL "Project")
|
||||
set(VIEWER_CHANNEL "${VIEWER_CHANNEL_BASE} ${VIEWER_CHANNEL_TYPE} ${VIEWER_CHANNEL_CODENAME}")
|
||||
else()
|
||||
set(VIEWER_CHANNEL "${VIEWER_CHANNEL_BASE} ${VIEWER_CHANNEL_TYPE}")
|
||||
endif()
|
||||
|
||||
string(TOLOWER "${VIEWER_CHANNEL_BASE}" VIEWER_BRANDING_ID)
|
||||
string(REPLACE " " "-" VIEWER_BRANDING_ID ${VIEWER_BRANDING_ID})
|
||||
set(VIEWER_BINARY_NAME "${VIEWER_BRANDING_ID}-bin" CACHE STRING
|
||||
"The name of the viewer executable to create.")
|
||||
|
||||
set(VIEWER_CHANNEL_BASE "Test" CACHE STRING "Viewer Channel Name")
|
||||
set(VIEWER_CHANNEL "${VIEWER_PRODUCT_NAME} ${VIEWER_CHANNEL_BASE}")
|
||||
string(TOLOWER ${VIEWER_CHANNEL} VIEWER_CHANNEL_LOWER)
|
||||
string(REPLACE " " "" VIEWER_CHANNEL_ONEWORD ${VIEWER_CHANNEL})
|
||||
set(VIEWER_CHANNEL_NOSPACE ${VIEWER_CHANNEL_ONEWORD} CACHE STRING "Prefix used for resulting artifacts.")
|
||||
|
||||
option(VIEWER_CHANNEL_GRK "Greek character(s) to represent the viewer channel for support purposes, override only for special branches" "")
|
||||
if (NOT VIEWER_CHANNEL_GRK)
|
||||
if (VIEWER_CHANNEL_BASE MATCHES "Test")
|
||||
set(VIEWER_CHANNEL_GRK "\\u03C4") # "τ"
|
||||
elseif (VIEWER_CHANNEL_BASE MATCHES "Alpha")
|
||||
set(VIEWER_CHANNEL_GRK "\\u03B1") # "α"
|
||||
elseif (VIEWER_CHANNEL_BASE MATCHES "Beta")
|
||||
set(VIEWER_CHANNEL_GRK "\\u03B2") # "β"
|
||||
endif ()
|
||||
if (VIEWER_CHANNEL_TYPE MATCHES "Test")
|
||||
set(VIEWER_CHANNEL_GRK "\\u03C4") # "τ"
|
||||
elseif (VIEWER_CHANNEL_TYPE MATCHES "Alpha")
|
||||
set(VIEWER_CHANNEL_GRK "\\u03B1") # "α"
|
||||
elseif (VIEWER_CHANNEL_TYPE MATCHES "Beta")
|
||||
set(VIEWER_CHANNEL_GRK "\\u03B2") # "β"
|
||||
endif ()
|
||||
endif (NOT VIEWER_CHANNEL_GRK)
|
||||
|
||||
if(VIEWER_CHANNEL_LOWER MATCHES "^${VIEWER_PRODUCT_NAME_LOWER} release")
|
||||
set(VIEWER_PACKAGE_ID "${VIEWER_PRODUCT_NAME}Release")
|
||||
set(VIEWER_EXE_STRING "${VIEWER_PRODUCT_NAME}Viewer")
|
||||
set(VIEWER_SHORTCUT_STRING "${VIEWER_PRODUCT_NAME} Viewer")
|
||||
else()
|
||||
set(VIEWER_PACKAGE_ID ${VIEWER_CHANNEL_ONEWORD})
|
||||
set(VIEWER_EXE_STRING ${VIEWER_CHANNEL_ONEWORD})
|
||||
set(VIEWER_SHORTCUT_STRING ${VIEWER_CHANNEL})
|
||||
endif()
|
||||
|
||||
set(VIEWER_CHANNEL_NOSPACE ${VIEWER_CHANNEL_ONEWORD} CACHE STRING "Prefix used for resulting artifacts.")
|
||||
|
||||
set(VIEWER_BRANDING_ID "singularity" CACHE STRING "Viewer branding id")
|
||||
|
||||
option(ENABLE_SIGNING "Enable signing the viewer" OFF)
|
||||
set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.")
|
||||
|
||||
set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
|
||||
# Compiler and toolchain options
|
||||
option(USESYSTEMLIBS "Use libraries from your system rather than Linden-supplied prebuilt libraries." OFF)
|
||||
option(STANDALONE "Use libraries from your system rather than Linden-supplied prebuilt libraries." OFF)
|
||||
if (USESYSTEMLIBS)
|
||||
set(STANDALONE ON)
|
||||
elseif (STANDALONE)
|
||||
set(USESYSTEMLIBS ON)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
||||
|
||||
|
||||
source_group("CMake Rules" FILES CMakeLists.txt)
|
||||
|
||||
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||
|
||||
@@ -3,9 +3,6 @@ include(Prebuilt)
|
||||
|
||||
if (NOT STANDALONE)
|
||||
use_prebuilt_binary(slvoice)
|
||||
if(LINUX)
|
||||
use_prebuilt_binary(fontconfig)
|
||||
endif(LINUX)
|
||||
else (NOT STANDALONE)
|
||||
# Download there even when using standalone.
|
||||
set(STANDALONE OFF)
|
||||
@@ -16,4 +13,9 @@ else (NOT STANDALONE)
|
||||
set(STANDALONE ON)
|
||||
endif(NOT STANDALONE)
|
||||
|
||||
if(LINUX)
|
||||
include(FindPkgConfig)
|
||||
pkg_check_modules(FONTCONFIG REQUIRED fontconfig)
|
||||
endif(LINUX)
|
||||
|
||||
use_prebuilt_binary(fonts)
|
||||
|
||||
48
indra/deps/CMakeLists.txt
Normal file
48
indra/deps/CMakeLists.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
project(deps)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
set(CMAKE_FOLDER "Third Party")
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
FetchContent_Declare(
|
||||
Catch2
|
||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||
GIT_TAG v2.11.0
|
||||
)
|
||||
FetchContent_Declare(
|
||||
fmt
|
||||
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
|
||||
GIT_TAG 6.1.2
|
||||
)
|
||||
FetchContent_Declare(
|
||||
absl
|
||||
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
|
||||
GIT_TAG 29235139149790f5afc430c11cec8f1eb1677607
|
||||
)
|
||||
|
||||
# This is a hack because absl has dumb cmake
|
||||
set(OLD_BUILD_TEST ${BUILD_TESTING})
|
||||
set(BUILD_TESTING OFF)
|
||||
FetchContent_MakeAvailable(absl)
|
||||
set(BUILD_TESTING ${OLD_BUILD_TEST})
|
||||
|
||||
# Supress warnings inside abseil under MSVC
|
||||
if(WINDOWS)
|
||||
target_compile_options(absl_strings PRIVATE /wd4018)
|
||||
target_compile_options(absl_str_format_internal PRIVATE /wd4018)
|
||||
target_compile_options(absl_flags_usage_internal PRIVATE /wd4018)
|
||||
endif()
|
||||
|
||||
|
||||
if (BUILD_TESTING)
|
||||
FetchContent_MakeAvailable(Catch2)
|
||||
endif()
|
||||
|
||||
#Download the rest of the libraries
|
||||
if(WINDOWS)
|
||||
FetchContent_MakeAvailable(fmt)
|
||||
endif()
|
||||
|
||||
unset(CMAKE_FOLDER)
|
||||
unset(CMAKE_POSITION_INDEPENDENT_CODE)
|
||||
@@ -1565,6 +1565,21 @@ BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name )
|
||||
param_name[1] = 1072; //"tattoo_green";
|
||||
param_name[2] = 1073; //"tattoo_blue";
|
||||
break;
|
||||
case TEX_HEAD_UNIVERSAL_TATTOO:
|
||||
case TEX_UPPER_UNIVERSAL_TATTOO:
|
||||
case TEX_LOWER_UNIVERSAL_TATTOO:
|
||||
case TEX_SKIRT_TATTOO:
|
||||
case TEX_HAIR_TATTOO:
|
||||
case TEX_EYES_TATTOO:
|
||||
case TEX_LEFT_ARM_TATTOO:
|
||||
case TEX_LEFT_LEG_TATTOO:
|
||||
case TEX_AUX1_TATTOO:
|
||||
case TEX_AUX2_TATTOO:
|
||||
case TEX_AUX3_TATTOO:
|
||||
param_name[0] = 1238; //"tattoo_universal_red";
|
||||
param_name[1] = 1239; //"tattoo_universal_green";
|
||||
param_name[2] = 1240; //"tattoo_universal_blue";
|
||||
break;
|
||||
|
||||
default:
|
||||
llassert(0);
|
||||
|
||||
@@ -27,8 +27,11 @@
|
||||
#include "linden_common.h"
|
||||
#include "llavatarappearancedefines.h"
|
||||
|
||||
const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512;
|
||||
const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512;
|
||||
#include "indra_constants.h"
|
||||
#include <utility>
|
||||
|
||||
const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 1024;
|
||||
const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 1024;
|
||||
const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2;
|
||||
|
||||
using namespace LLAvatarAppearanceDefines;
|
||||
@@ -65,12 +68,30 @@ LLAvatarAppearanceDictionary::Textures::Textures()
|
||||
addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
|
||||
addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
|
||||
|
||||
addEntry(TEX_HEAD_UNIVERSAL_TATTOO, new TextureEntry("head_universal_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_UPPER_UNIVERSAL_TATTOO, new TextureEntry("upper_universal_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_LOWER_UNIVERSAL_TATTOO, new TextureEntry("lower_universal_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_SKIRT_TATTOO, new TextureEntry("skirt_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_HAIR_TATTOO, new TextureEntry("hair_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_EYES_TATTOO, new TextureEntry("eyes_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_LEFT_ARM_TATTOO, new TextureEntry("leftarm_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_LEFT_LEG_TATTOO, new TextureEntry("leftleg_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_AUX1_TATTOO, new TextureEntry("aux1_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_AUX2_TATTOO, new TextureEntry("aux2_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
addEntry(TEX_AUX3_TATTOO, new TextureEntry("aux3_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL));
|
||||
|
||||
|
||||
addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD, "head"));
|
||||
addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER, "upper"));
|
||||
addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER, "lower"));
|
||||
addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES, "eyes"));
|
||||
addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR, "hair"));
|
||||
addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT, "skirt"));
|
||||
addEntry(TEX_LEFT_ARM_BAKED, new TextureEntry("leftarm-baked", FALSE, BAKED_LEFT_ARM, "leftarm"));
|
||||
addEntry(TEX_LEFT_LEG_BAKED, new TextureEntry("leftleg-baked", FALSE, BAKED_LEFT_LEG, "leftleg"));
|
||||
addEntry(TEX_AUX1_BAKED, new TextureEntry("aux1-baked", FALSE, BAKED_AUX1, "aux1"));
|
||||
addEntry(TEX_AUX2_BAKED, new TextureEntry("aux2-baked", FALSE, BAKED_AUX2, "aux2"));
|
||||
addEntry(TEX_AUX3_BAKED, new TextureEntry("aux3-baked", FALSE, BAKED_AUX3, "aux3"));
|
||||
}
|
||||
|
||||
LLAvatarAppearanceDictionary::BakedTextures::BakedTextures()
|
||||
@@ -78,35 +99,60 @@ LLAvatarAppearanceDictionary::BakedTextures::BakedTextures()
|
||||
// Baked textures
|
||||
addEntry(BAKED_HEAD, new BakedEntry(TEX_HEAD_BAKED,
|
||||
"head", "a4b9dc38-e13b-4df9-b284-751efb0566ff",
|
||||
3, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA,
|
||||
5, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_HAIR, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
|
||||
4, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA, TEX_HEAD_UNIVERSAL_TATTOO,
|
||||
6, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_HAIR, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA, LLWearableType::WT_UNIVERSAL));
|
||||
|
||||
addEntry(BAKED_UPPER, new BakedEntry(TEX_UPPER_BAKED,
|
||||
"upper_body", "5943ff64-d26c-4a90-a8c0-d61f56bd98d4",
|
||||
7, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET,
|
||||
TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA,
|
||||
8, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_SHIRT, LLWearableType::WT_JACKET, LLWearableType::WT_GLOVES, LLWearableType::WT_UNDERSHIRT, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
|
||||
8, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET,
|
||||
TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA, TEX_UPPER_UNIVERSAL_TATTOO,
|
||||
9, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_SHIRT, LLWearableType::WT_JACKET, LLWearableType::WT_GLOVES, LLWearableType::WT_UNDERSHIRT, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA, LLWearableType::WT_UNIVERSAL));
|
||||
|
||||
addEntry(BAKED_LOWER, new BakedEntry(TEX_LOWER_BAKED,
|
||||
"lower_body", "2944ee70-90a7-425d-a5fb-d749c782ed7d",
|
||||
8, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES, TEX_LOWER_SOCKS,
|
||||
TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA,
|
||||
9, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_PANTS, LLWearableType::WT_SHOES, LLWearableType::WT_SOCKS, LLWearableType::WT_JACKET, LLWearableType::WT_UNDERPANTS, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
|
||||
9, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES, TEX_LOWER_SOCKS,
|
||||
TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA, TEX_LOWER_UNIVERSAL_TATTOO,
|
||||
10, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_PANTS, LLWearableType::WT_SHOES, LLWearableType::WT_SOCKS, LLWearableType::WT_JACKET, LLWearableType::WT_UNDERPANTS, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA, LLWearableType::WT_UNIVERSAL));
|
||||
|
||||
addEntry(BAKED_EYES, new BakedEntry(TEX_EYES_BAKED,
|
||||
"eyes", "27b1bc0f-979f-4b13-95fe-b981c2ba9788",
|
||||
2, TEX_EYES_IRIS, TEX_EYES_ALPHA,
|
||||
2, LLWearableType::WT_EYES, LLWearableType::WT_ALPHA));
|
||||
3, TEX_EYES_IRIS, TEX_EYES_TATTOO, TEX_EYES_ALPHA,
|
||||
3, LLWearableType::WT_EYES, LLWearableType::WT_UNIVERSAL, LLWearableType::WT_ALPHA));
|
||||
|
||||
addEntry(BAKED_SKIRT, new BakedEntry(TEX_SKIRT_BAKED,
|
||||
"skirt", "03e7e8cb-1368-483b-b6f3-74850838ba63",
|
||||
1, TEX_SKIRT,
|
||||
1, LLWearableType::WT_SKIRT));
|
||||
2, TEX_SKIRT, TEX_SKIRT_TATTOO,
|
||||
2, LLWearableType::WT_SKIRT, LLWearableType::WT_UNIVERSAL ));
|
||||
|
||||
addEntry(BAKED_HAIR, new BakedEntry(TEX_HAIR_BAKED,
|
||||
"hair", "a60e85a9-74e8-48d8-8a2d-8129f28d9b61",
|
||||
2, TEX_HAIR, TEX_HAIR_ALPHA,
|
||||
2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA));
|
||||
3, TEX_HAIR, TEX_HAIR_TATTOO, TEX_HAIR_ALPHA,
|
||||
3, LLWearableType::WT_HAIR, LLWearableType::WT_UNIVERSAL, LLWearableType::WT_ALPHA));
|
||||
|
||||
addEntry(BAKED_LEFT_ARM, new BakedEntry(TEX_LEFT_ARM_BAKED,
|
||||
"leftarm", "9f39febf-22d7-0087-79d1-e9e8c6c9ed19",
|
||||
1, TEX_LEFT_ARM_TATTOO,
|
||||
1, LLWearableType::WT_UNIVERSAL));
|
||||
|
||||
addEntry(BAKED_LEFT_LEG, new BakedEntry(TEX_LEFT_LEG_BAKED,
|
||||
"leftleg", "054a7a58-8ed5-6386-0add-3b636fb28b78",
|
||||
1, TEX_LEFT_LEG_TATTOO,
|
||||
1, LLWearableType::WT_UNIVERSAL));
|
||||
|
||||
addEntry(BAKED_AUX1, new BakedEntry(TEX_AUX1_BAKED,
|
||||
"aux1", "790c11be-b25c-c17e-b4d2-6a4ad786b752",
|
||||
1, TEX_AUX1_TATTOO,
|
||||
1, LLWearableType::WT_UNIVERSAL));
|
||||
|
||||
addEntry(BAKED_AUX2, new BakedEntry(TEX_AUX2_BAKED,
|
||||
"aux2", "d78c478f-48c7-5928-5864-8d99fb1f521e",
|
||||
1, TEX_AUX2_TATTOO,
|
||||
1, LLWearableType::WT_UNIVERSAL));
|
||||
|
||||
addEntry(BAKED_AUX3, new BakedEntry(TEX_AUX3_BAKED,
|
||||
"aux3", "6a95dd53-edd9-aac8-f6d3-27ed99f3c3eb",
|
||||
1, TEX_AUX3_TATTOO,
|
||||
1, LLWearableType::WT_UNIVERSAL));
|
||||
}
|
||||
|
||||
LLAvatarAppearanceDictionary::MeshEntries::MeshEntries()
|
||||
@@ -267,3 +313,112 @@ LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIn
|
||||
return getInstance()->getTexture(index)->mWearableType;
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLAvatarAppearanceDictionary::isBakedImageId(const LLUUID& id)
|
||||
{
|
||||
if ((id == IMG_USE_BAKED_EYES) || (id == IMG_USE_BAKED_HAIR) || (id == IMG_USE_BAKED_HEAD) || (id == IMG_USE_BAKED_LOWER) || (id == IMG_USE_BAKED_SKIRT) || (id == IMG_USE_BAKED_UPPER)
|
||||
|| (id == IMG_USE_BAKED_LEFTARM) || (id == IMG_USE_BAKED_LEFTLEG) || (id == IMG_USE_BAKED_AUX1) || (id == IMG_USE_BAKED_AUX2) || (id == IMG_USE_BAKED_AUX3) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// static
|
||||
EBakedTextureIndex LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(const LLUUID& id)
|
||||
{
|
||||
if (id == IMG_USE_BAKED_EYES)
|
||||
{
|
||||
return BAKED_EYES;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_HAIR)
|
||||
{
|
||||
return BAKED_HAIR;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_HEAD)
|
||||
{
|
||||
return BAKED_HEAD;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_LOWER)
|
||||
{
|
||||
return BAKED_LOWER;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_SKIRT)
|
||||
{
|
||||
return BAKED_SKIRT;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_UPPER)
|
||||
{
|
||||
return BAKED_UPPER;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_LEFTARM)
|
||||
{
|
||||
return BAKED_LEFT_ARM;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_LEFTLEG)
|
||||
{
|
||||
return BAKED_LEFT_LEG;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_AUX1)
|
||||
{
|
||||
return BAKED_AUX1;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_AUX2)
|
||||
{
|
||||
return BAKED_AUX2;
|
||||
}
|
||||
else if (id == IMG_USE_BAKED_AUX3)
|
||||
{
|
||||
return BAKED_AUX3;
|
||||
}
|
||||
|
||||
return BAKED_NUM_INDICES;
|
||||
}
|
||||
|
||||
//static
|
||||
LLUUID LLAvatarAppearanceDictionary::localTextureIndexToMagicId(ETextureIndex t)
|
||||
{
|
||||
LLUUID id = LLUUID::null;
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case LLAvatarAppearanceDefines::TEX_HEAD_BAKED:
|
||||
id = IMG_USE_BAKED_HEAD;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_UPPER_BAKED:
|
||||
id = IMG_USE_BAKED_UPPER;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_LOWER_BAKED:
|
||||
id = IMG_USE_BAKED_LOWER;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_EYES_BAKED:
|
||||
id = IMG_USE_BAKED_EYES;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_SKIRT_BAKED:
|
||||
id = IMG_USE_BAKED_SKIRT;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_HAIR_BAKED:
|
||||
id = IMG_USE_BAKED_HAIR;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_LEFT_ARM_BAKED:
|
||||
id = IMG_USE_BAKED_LEFTARM;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_LEFT_LEG_BAKED:
|
||||
id = IMG_USE_BAKED_LEFTLEG;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_AUX1_BAKED:
|
||||
id = IMG_USE_BAKED_AUX1;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_AUX2_BAKED:
|
||||
id = IMG_USE_BAKED_AUX2;
|
||||
break;
|
||||
case LLAvatarAppearanceDefines::TEX_AUX3_BAKED:
|
||||
id = IMG_USE_BAKED_AUX3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/**
|
||||
* @file llavatarappearancedefines.h
|
||||
* @brief Various LLAvatarAppearance related definitions
|
||||
@@ -78,6 +79,22 @@ enum ETextureIndex
|
||||
TEX_HEAD_TATTOO,
|
||||
TEX_UPPER_TATTOO,
|
||||
TEX_LOWER_TATTOO,
|
||||
TEX_HEAD_UNIVERSAL_TATTOO,
|
||||
TEX_UPPER_UNIVERSAL_TATTOO,
|
||||
TEX_LOWER_UNIVERSAL_TATTOO,
|
||||
TEX_SKIRT_TATTOO,
|
||||
TEX_HAIR_TATTOO,
|
||||
TEX_EYES_TATTOO,
|
||||
TEX_LEFT_ARM_TATTOO,
|
||||
TEX_LEFT_LEG_TATTOO,
|
||||
TEX_AUX1_TATTOO,
|
||||
TEX_AUX2_TATTOO,
|
||||
TEX_AUX3_TATTOO,
|
||||
TEX_LEFT_ARM_BAKED, // Pre-composited
|
||||
TEX_LEFT_LEG_BAKED, // Pre-composited
|
||||
TEX_AUX1_BAKED, // Pre-composited
|
||||
TEX_AUX2_BAKED, // Pre-composited
|
||||
TEX_AUX3_BAKED, // Pre-composited
|
||||
TEX_NUM_INDICES
|
||||
};
|
||||
|
||||
@@ -89,6 +106,11 @@ enum EBakedTextureIndex
|
||||
BAKED_EYES,
|
||||
BAKED_SKIRT,
|
||||
BAKED_HAIR,
|
||||
BAKED_LEFT_ARM,
|
||||
BAKED_LEFT_LEG,
|
||||
BAKED_AUX1,
|
||||
BAKED_AUX2,
|
||||
BAKED_AUX3,
|
||||
BAKED_NUM_INDICES
|
||||
};
|
||||
|
||||
@@ -224,6 +246,9 @@ public:
|
||||
// Given a texture entry, determine which wearable type owns it.
|
||||
static LLWearableType::EType getTEWearableType(ETextureIndex index);
|
||||
|
||||
static BOOL isBakedImageId(const LLUUID& id);
|
||||
static EBakedTextureIndex assetIdToBakedTextureIndex(const LLUUID& id);
|
||||
static LLUUID localTextureIndexToMagicId(ETextureIndex t);
|
||||
}; // End LLAvatarAppearanceDictionary
|
||||
|
||||
} // End namespace LLAvatarAppearanceDefines
|
||||
|
||||
@@ -184,7 +184,7 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
|
||||
{
|
||||
LLTexLayerSet *layer_set = NULL;
|
||||
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
|
||||
if (texture_dict->mIsUsedByBakedTexture)
|
||||
if (texture_dict && texture_dict->mIsUsedByBakedTexture)
|
||||
{
|
||||
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
|
||||
|
||||
@@ -197,7 +197,7 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_ERRS() << "could not find layerset for LTO in wearable!" << LL_ENDL;
|
||||
LL_WARNS() << "could not find layerset for LTO in wearable!" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,6 +438,12 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream,
|
||||
return LLWearable::FAILURE;
|
||||
}
|
||||
|
||||
if (te >= ETextureIndex::TEX_NUM_INDICES) //createLayers() converts to ETextureIndex
|
||||
{
|
||||
LL_WARNS() << "Bad Wearable asset: bad texture index: " << te << LL_ENDL;
|
||||
return LLWearable::FAILURE;
|
||||
}
|
||||
|
||||
if( !LLUUID::validate( uuid_buffer ) )
|
||||
{
|
||||
LL_WARNS() << "Bad Wearable asset: bad texture uuid: "
|
||||
|
||||
@@ -98,6 +98,7 @@ LLWearableDictionary::LLWearableDictionary()
|
||||
addEntry(LLWearableType::WT_SKIRT, new WearableEntry("skirt", "New Skirt", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
|
||||
addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
|
||||
addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
|
||||
addEntry(LLWearableType::WT_UNIVERSAL, new WearableEntry("universal", "New Universal", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_UNIVERSAL, FALSE, TRUE));
|
||||
|
||||
// [SL:KB] - Patch: Appearance-Misc | Checked: 2011-05-29 (Catznip-2.6)
|
||||
addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, FALSE));
|
||||
|
||||
@@ -54,10 +54,12 @@ public:
|
||||
WT_ALPHA = 13,
|
||||
WT_TATTOO = 14,
|
||||
WT_PHYSICS = 15,
|
||||
WT_UNKNOWN = 16, // Singu note: used for corrupt wearables that do not have their type set in the inventory database.
|
||||
WT_UNIVERSAL = 16,
|
||||
WT_UNKNOWN = 17, // Singu note: used for corrupt wearables that do not have their type set in the inventory database.
|
||||
// While all the above values are serialized and stored in the database, this value is local only:
|
||||
// When a new item with value 16 is added by upstream, just increase this value to 17 (and WT_COUNT to 18).
|
||||
WT_COUNT = 17,
|
||||
// When a new item with value 17 is added by upstream, just increase this value to 18 (and WT_COUNT to 19).
|
||||
// Keep WT_UNKNOWN and WT_COUNT in sync with llinventory.cpp
|
||||
WT_COUNT = 18,
|
||||
|
||||
WT_INVALID = 255,
|
||||
WT_NONE = -1,
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
project(llaudio)
|
||||
|
||||
include(00-Common)
|
||||
include(Audio)
|
||||
include(LLAudio)
|
||||
include(FMODSTUDIO)
|
||||
include(OPENAL)
|
||||
include(LLCommon)
|
||||
@@ -12,10 +10,6 @@ include(LLMath)
|
||||
include(LLMessage)
|
||||
include(LLVFS)
|
||||
|
||||
if (FMOD)
|
||||
include_directories(${FMOD_INCLUDE_DIR})
|
||||
endif(FMOD)
|
||||
|
||||
include_directories(
|
||||
${LLAUDIO_INCLUDE_DIRS}
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
@@ -26,7 +20,7 @@ include_directories(
|
||||
${VORBISENC_INCLUDE_DIRS}
|
||||
${VORBISFILE_INCLUDE_DIRS}
|
||||
${VORBIS_INCLUDE_DIRS}
|
||||
${OPENAL_INCLUDE_DIRS}
|
||||
${OPENAL_LIB_INCLUDE_DIRS}
|
||||
${FREEAULT_LIB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
@@ -49,7 +43,10 @@ set(llaudio_HEADER_FILES
|
||||
llwindgen.h
|
||||
)
|
||||
|
||||
if (FMODSTUDIO)
|
||||
if (USE_FMODSTUDIO)
|
||||
include_directories(
|
||||
${FMODSTUDIO_INCLUDE_DIR}
|
||||
)
|
||||
list(APPEND llaudio_SOURCE_FILES
|
||||
llaudioengine_fmodstudio.cpp
|
||||
lllistener_fmodstudio.cpp
|
||||
@@ -61,7 +58,7 @@ if (FMODSTUDIO)
|
||||
lllistener_fmodstudio.h
|
||||
llstreamingaudio_fmodstudio.h
|
||||
)
|
||||
endif (FMODSTUDIO)
|
||||
endif (USE_FMODSTUDIO)
|
||||
|
||||
if (OPENAL)
|
||||
list(APPEND llaudio_SOURCE_FILES
|
||||
|
||||
@@ -13,7 +13,6 @@ include(Boost)
|
||||
include(OpenSSL)
|
||||
include(LLSharedLibs)
|
||||
include(Json)
|
||||
include(GoogleBreakpad)
|
||||
include(Copy3rdPartyLibs)
|
||||
include(ZLIB)
|
||||
include(URIPARSER)
|
||||
@@ -270,12 +269,6 @@ list(APPEND llcommon_SOURCE_FILES ${cwdebug_SOURCE_FILES})
|
||||
|
||||
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
|
||||
|
||||
if(NOT WORD_SIZE EQUAL 32)
|
||||
if(NOT WINDOWS)
|
||||
add_definitions(-fPIC)
|
||||
endif(NOT WINDOWS)
|
||||
endif(NOT WORD_SIZE EQUAL 32)
|
||||
|
||||
if(LLCOMMON_LINK_SHARED)
|
||||
add_library (llcommon SHARED ${llcommon_SOURCE_FILES})
|
||||
if(WINDOWS)
|
||||
@@ -287,11 +280,12 @@ else(LLCOMMON_LINK_SHARED)
|
||||
add_library (llcommon ${llcommon_SOURCE_FILES})
|
||||
endif(LLCOMMON_LINK_SHARED)
|
||||
|
||||
set_target_properties(llcommon PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
||||
target_link_libraries(
|
||||
llcommon
|
||||
PUBLIC
|
||||
absl::hash
|
||||
${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}
|
||||
${APRUTIL_LIBRARIES}
|
||||
${APR_LIBRARIES}
|
||||
${EXPAT_LIBRARIES}
|
||||
@@ -306,6 +300,7 @@ target_link_libraries(
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${CORESERVICES_LIBRARY}
|
||||
${URIPARSER_LIBRARY}
|
||||
${RT_LIBRARY}
|
||||
)
|
||||
|
||||
if (DARWIN)
|
||||
|
||||
@@ -45,3 +45,15 @@ const LLUUID GOVERNOR_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1");
|
||||
const LLUUID REALESTATE_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1");
|
||||
// Maintenance's group id.
|
||||
const LLUUID MAINTENANCE_GROUP_ID("dc7b21cd-3c89-fcaa-31c8-25f9ffd224cd");
|
||||
|
||||
const LLUUID IMG_USE_BAKED_HEAD ("5a9f4a74-30f2-821c-b88d-70499d3e7183");
|
||||
const LLUUID IMG_USE_BAKED_UPPER ("ae2de45c-d252-50b8-5c6e-19f39ce79317");
|
||||
const LLUUID IMG_USE_BAKED_LOWER ("24daea5f-0539-cfcf-047f-fbc40b2786ba");
|
||||
const LLUUID IMG_USE_BAKED_EYES ("52cc6bb6-2ee5-e632-d3ad-50197b1dcb8a");
|
||||
const LLUUID IMG_USE_BAKED_SKIRT ("43529ce8-7faa-ad92-165a-bc4078371687");
|
||||
const LLUUID IMG_USE_BAKED_HAIR ("09aac1fb-6bce-0bee-7d44-caac6dbb6c63");
|
||||
const LLUUID IMG_USE_BAKED_LEFTARM ("ff62763f-d60a-9855-890b-0c96f8f8cd98");
|
||||
const LLUUID IMG_USE_BAKED_LEFTLEG ("8e915e25-31d1-cc95-ae08-d58a47488251");
|
||||
const LLUUID IMG_USE_BAKED_AUX1 ("9742065b-19b5-297c-858a-29711d539043");
|
||||
const LLUUID IMG_USE_BAKED_AUX2 ("03642e83-2bd1-4eb9-34b4-4c47ed586d2d");
|
||||
const LLUUID IMG_USE_BAKED_AUX3 ("edd51b77-fc10-ce7a-4b3d-011dfc349e4f");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/**
|
||||
* @file indra_constants.h
|
||||
* @brief some useful short term constants for Indra
|
||||
@@ -294,6 +295,19 @@ const U32 START_LOCATION_ID_COUNT = 6;
|
||||
// group constants
|
||||
const U32 GROUP_MIN_SIZE = 2;
|
||||
|
||||
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_HEAD;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_UPPER;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_LOWER;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_EYES;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_SKIRT;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_HAIR;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_LEFTARM;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_LEFTLEG;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX1;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX2;
|
||||
LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX3;
|
||||
|
||||
// radius within which a chat message is fully audible
|
||||
const F32 CHAT_WHISPER_RADIUS = 10.f;
|
||||
const F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
@@ -354,13 +368,6 @@ const U32 MAP_ITEM_CLASSIFIED = 0x08;
|
||||
const U32 MAP_ITEM_ADULT_EVENT = 0x09;
|
||||
const U32 MAP_ITEM_LAND_FOR_SALE_ADULT = 0x0a;
|
||||
|
||||
// Crash reporter behavior
|
||||
const char* const CRASH_SETTINGS_FILE = "settings_crash_behavior.xml";
|
||||
const char* const CRASH_BEHAVIOR_SETTING = "CrashSubmitBehavior";
|
||||
const S32 CRASH_BEHAVIOR_ASK = 0;
|
||||
const S32 CRASH_BEHAVIOR_ALWAYS_SEND = 1;
|
||||
const S32 CRASH_BEHAVIOR_NEVER_SEND = 2;
|
||||
|
||||
// Export/Import return values
|
||||
const S32 EXPORT_SUCCESS = 0;
|
||||
const S32 EXPORT_ERROR_PERMISSIONS = -1;
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llapp.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include "llapp.h"
|
||||
|
||||
#ifdef LL_DARWIN
|
||||
#include <sys/types.h>
|
||||
@@ -45,7 +44,6 @@
|
||||
#include "llstl.h" // for DeletePointer()
|
||||
#include "llstring.h"
|
||||
#include "lleventtimer.h"
|
||||
#include "exception_handler.h"
|
||||
|
||||
//
|
||||
// Signal handling
|
||||
@@ -57,12 +55,6 @@
|
||||
|
||||
LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop);
|
||||
BOOL ConsoleCtrlHandler(DWORD fdwCtrlType);
|
||||
bool windows_post_minidump_callback(const wchar_t* dump_path,
|
||||
const wchar_t* minidump_id,
|
||||
void* context,
|
||||
EXCEPTION_POINTERS* exinfo,
|
||||
MDRawAssertionInfo* assertion,
|
||||
bool succeeded);
|
||||
#else
|
||||
# include <signal.h>
|
||||
# include <unistd.h> // for fork()
|
||||
@@ -70,18 +62,6 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
|
||||
void setup_signals();
|
||||
void default_unix_signal_handler(int signum, siginfo_t *info, void *);
|
||||
|
||||
#if LL_LINUX
|
||||
#include "client/linux/handler/minidump_descriptor.h"
|
||||
static bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc,
|
||||
void* context,
|
||||
bool succeeded);
|
||||
#else
|
||||
// Called by breakpad exception handler after the minidump has been generated.
|
||||
bool unix_post_minidump_callback(const char *dump_dir,
|
||||
const char *minidump_id,
|
||||
void *context, bool succeeded);
|
||||
#endif
|
||||
|
||||
# if LL_DARWIN
|
||||
/* OSX doesn't support SIGRT* */
|
||||
S32 LL_SMACKDOWN_SIGNAL = SIGUSR1;
|
||||
@@ -98,7 +78,7 @@ S32 LL_HEARTBEAT_SIGNAL = (SIGRTMAX >= 0) ? (SIGRTMAX-0) : SIGUSR2;
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
// the static application instance
|
||||
LLApp* LLApp::sApplication = NULL;
|
||||
LLApp* LLApp::sApplication = nullptr;
|
||||
|
||||
// Allows the generation of core files for post mortem under gdb
|
||||
// and disables crashlogger
|
||||
@@ -110,7 +90,7 @@ BOOL LLApp::sLogInSignal = FALSE;
|
||||
|
||||
// static
|
||||
LLApp::EAppStatus LLApp::sStatus = LLApp::APP_STATUS_STOPPED; // Keeps track of application status
|
||||
LLAppErrorHandler LLApp::sErrorHandler = NULL;
|
||||
LLAppErrorHandler LLApp::sErrorHandler = nullptr;
|
||||
BOOL LLApp::sErrorThreadRunning = FALSE;
|
||||
#if !LL_WINDOWS
|
||||
LLApp::child_map LLApp::sChildMap;
|
||||
@@ -119,13 +99,12 @@ LLAppChildCallback LLApp::sDefaultChildCallback = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
LLApp::LLApp() : mThreadErrorp(NULL)
|
||||
LLApp::LLApp()
|
||||
: mThreadErrorp(nullptr)
|
||||
{
|
||||
commonCtor();
|
||||
}
|
||||
|
||||
static void* sCrashLoggerReserve = NULL;
|
||||
|
||||
void LLApp::commonCtor()
|
||||
{
|
||||
// Set our status to running
|
||||
@@ -150,34 +129,11 @@ void LLApp::commonCtor()
|
||||
// Set the application to this instance.
|
||||
sApplication = this;
|
||||
|
||||
mExceptionHandler = 0;
|
||||
|
||||
#if LL_WINDOWS
|
||||
sCrashLoggerReserve = VirtualAlloc(NULL, 512*1024, MEM_COMMIT|MEM_RESERVE, PAGE_NOACCESS);
|
||||
#else
|
||||
sCrashLoggerReserve = malloc(512*1024);
|
||||
#endif
|
||||
|
||||
// initialize the buffer to write the minidump filename to
|
||||
// (this is used to avoid allocating memory in the crash handler)
|
||||
memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH);
|
||||
mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
static bool clear_CrashLoggerReserve_callback(void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion)
|
||||
{
|
||||
VirtualFree(sCrashLoggerReserve, 0, MEM_RELEASE);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static bool clear_CrashLoggerReserve_callback(void* context)
|
||||
{
|
||||
free(sCrashLoggerReserve);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
LLApp::LLApp(LLErrorThread *error_thread) :
|
||||
mThreadErrorp(error_thread)
|
||||
{
|
||||
@@ -198,11 +154,9 @@ LLApp::~LLApp()
|
||||
if (mThreadErrorp)
|
||||
{
|
||||
delete mThreadErrorp;
|
||||
mThreadErrorp = NULL;
|
||||
mThreadErrorp = nullptr;
|
||||
}
|
||||
|
||||
if(mExceptionHandler != 0) delete mExceptionHandler;
|
||||
|
||||
LLCommon::cleanupClass();
|
||||
}
|
||||
|
||||
@@ -216,8 +170,8 @@ LLApp* LLApp::instance()
|
||||
LLSD LLApp::getOption(const std::string& name) const
|
||||
{
|
||||
LLSD rv;
|
||||
LLSD::array_const_iterator iter = mOptions.beginArray();
|
||||
LLSD::array_const_iterator end = mOptions.endArray();
|
||||
auto iter = mOptions.beginArray();
|
||||
auto end = mOptions.endArray();
|
||||
for(; iter != end; ++iter)
|
||||
{
|
||||
rv = (*iter)[name];
|
||||
@@ -264,9 +218,9 @@ bool LLApp::parseCommandOptions(int argc, char** argv)
|
||||
|
||||
#if LL_WINDOWS
|
||||
//Windows changed command line parsing. Deal with it.
|
||||
S32 slen = value.length() - 1;
|
||||
S32 start = 0;
|
||||
S32 end = slen;
|
||||
size_t slen = value.length() - 1;
|
||||
size_t start = 0;
|
||||
size_t end = slen;
|
||||
if (argv[ii][start]=='"')start++;
|
||||
if (argv[ii][end]=='"')end--;
|
||||
if (start!=0 || end!=slen)
|
||||
@@ -343,92 +297,17 @@ void LLApp::setupErrorHandling()
|
||||
// Error handling is done by starting up an error handling thread, which just sleeps and
|
||||
// occasionally checks to see if the app is in an error state, and sees if it needs to be run.
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
#if LL_SEND_CRASH_REPORTS
|
||||
EnableCrashingOnCrashes();
|
||||
|
||||
// This sets a callback to handle w32 signals to the console window.
|
||||
// The viewer shouldn't be affected, sicne its a windowed app.
|
||||
SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE);
|
||||
|
||||
// Install the Google Breakpad crash handler for Windows
|
||||
if(mExceptionHandler == 0)
|
||||
{
|
||||
mExceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
std::wstring(mDumpPath.begin(),mDumpPath.end()), //Dump path
|
||||
clear_CrashLoggerReserve_callback,
|
||||
windows_post_minidump_callback,
|
||||
0,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||
if (mExceptionHandler)
|
||||
{
|
||||
mExceptionHandler->set_handle_debug_exceptions(true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if !LL_WINDOWS
|
||||
//
|
||||
// Start up signal handling.
|
||||
//
|
||||
// There are two different classes of signals. Synchronous signals are delivered to a specific
|
||||
// thread, asynchronous signals can be delivered to any thread (in theory)
|
||||
//
|
||||
|
||||
setup_signals();
|
||||
|
||||
// Add google breakpad exception handler configured for Darwin/Linux.
|
||||
bool installHandler = true;
|
||||
#if LL_DARWIN
|
||||
// For the special case of Darwin, we do not want to install the handler if
|
||||
// the process is being debugged as the app will exit with value ABRT (6) if
|
||||
// we do. Unfortunately, the code below which performs that test relies on
|
||||
// the structure kinfo_proc which has been tagged by apple as an unstable
|
||||
// API. We disable this test for shipping versions to avoid conflicts with
|
||||
// future releases of Darwin. This test is really only needed for developers
|
||||
// starting the app from a debugger anyway.
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
int mib[4];
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PID;
|
||||
mib[3] = getpid();
|
||||
|
||||
struct kinfo_proc info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
size_t size = sizeof(info);
|
||||
int result = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
|
||||
if((result == 0) || (errno == ENOMEM))
|
||||
{
|
||||
// P_TRACED flag is set, so this process is being debugged; do not install
|
||||
// the handler
|
||||
if(info.kp_proc.p_flag & P_TRACED) installHandler = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to discover if the process is being debugged; default to
|
||||
// installing the handler.
|
||||
installHandler = true;
|
||||
}
|
||||
|
||||
if(installHandler && (mExceptionHandler == 0))
|
||||
{
|
||||
mExceptionHandler = new google_breakpad::ExceptionHandler(mDumpPath, clear_CrashLoggerReserve_callback, &unix_post_minidump_callback, 0, true, 0);
|
||||
}
|
||||
#endif
|
||||
#elif LL_LINUX
|
||||
if(installHandler && (mExceptionHandler == 0))
|
||||
{
|
||||
if (mDumpPath.empty())
|
||||
{
|
||||
mDumpPath = "/tmp";
|
||||
}
|
||||
google_breakpad::MinidumpDescriptor desc(mDumpPath);
|
||||
mExceptionHandler = new google_breakpad::ExceptionHandler(desc, clear_CrashLoggerReserve_callback, unix_minidump_callback, NULL, true, -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ! LL_WINDOWS
|
||||
#if !defined(USE_CRASHPAD)
|
||||
startErrorThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -466,7 +345,6 @@ void LLApp::setErrorHandler(LLAppErrorHandler handler)
|
||||
LLApp::sErrorHandler = handler;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLApp::runErrorHandler()
|
||||
{
|
||||
@@ -479,7 +357,6 @@ void LLApp::runErrorHandler()
|
||||
LLApp::setStopped();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLApp::setStatus(EAppStatus status)
|
||||
{
|
||||
@@ -494,43 +371,12 @@ void LLApp::setError()
|
||||
setStatus(APP_STATUS_ERROR);
|
||||
}
|
||||
|
||||
void LLApp::setMiniDumpDir(const std::string &path)
|
||||
{
|
||||
if (path.empty())
|
||||
{
|
||||
mDumpPath = "/tmp";
|
||||
}
|
||||
else
|
||||
{
|
||||
mDumpPath = path;
|
||||
}
|
||||
|
||||
if(mExceptionHandler == 0) return;
|
||||
#ifdef LL_WINDOWS
|
||||
wchar_t buffer[MAX_MINDUMP_PATH_LENGTH];
|
||||
mbstowcs(buffer, mDumpPath.c_str(), MAX_MINDUMP_PATH_LENGTH);
|
||||
mExceptionHandler->set_dump_path(std::wstring(buffer));
|
||||
#elif LL_LINUX
|
||||
//google_breakpad::MinidumpDescriptor desc("/tmp"); //path works in debug fails in production inside breakpad lib so linux gets a little less stack reporting until it is patched.
|
||||
google_breakpad::MinidumpDescriptor desc(mDumpPath); //path works in debug fails in production inside breakpad lib so linux gets a little less stack reporting until it is patched.
|
||||
mExceptionHandler->set_minidump_descriptor(desc);
|
||||
#else
|
||||
mExceptionHandler->set_dump_path(mDumpPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLApp::setDebugFileNames(const std::string &path)
|
||||
{
|
||||
mStaticDebugFileName = path + "static_debug_info.log";
|
||||
mDynamicDebugFileName = path + "dynamic_debug_info.log";
|
||||
}
|
||||
|
||||
void LLApp::writeMiniDump()
|
||||
{
|
||||
if(mExceptionHandler == 0) return;
|
||||
mExceptionHandler->WriteMinidump();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLApp::setQuitting()
|
||||
{
|
||||
@@ -585,13 +431,6 @@ bool LLApp::isExiting()
|
||||
|
||||
void LLApp::disableCrashlogger()
|
||||
{
|
||||
// Disable Breakpad exception handler.
|
||||
if (mExceptionHandler != 0)
|
||||
{
|
||||
delete mExceptionHandler;
|
||||
mExceptionHandler = 0;
|
||||
}
|
||||
|
||||
sDisableCrashlogger = TRUE;
|
||||
}
|
||||
|
||||
@@ -660,12 +499,6 @@ LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *except
|
||||
ms_sleep(10);
|
||||
}
|
||||
|
||||
//
|
||||
// Generate a minidump if we can.
|
||||
//
|
||||
// TODO: This needs to be ported over form the viewer-specific
|
||||
// LLWinDebug class
|
||||
|
||||
//
|
||||
// At this point, we always want to exit the app. There's no graceful
|
||||
// recovery for an unhandled exception.
|
||||
@@ -965,150 +798,4 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LL_LINUX
|
||||
bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded)
|
||||
{
|
||||
// Copy minidump file path into fixed buffer in the app instance to avoid
|
||||
// heap allocations in a crash handler.
|
||||
|
||||
// path format: <dump_dir>/<minidump_id>.dmp
|
||||
|
||||
//HACK: *path points to the buffer in getMiniDumpFilename which has already allocated space
|
||||
//to avoid doing allocation during crash.
|
||||
char * path = LLApp::instance()->getMiniDumpFilename();
|
||||
int dir_path_len = strlen(path);
|
||||
|
||||
// The path must not be truncated.
|
||||
S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH - dir_path_len;
|
||||
|
||||
llassert( (remaining - strlen(minidump_desc.path())) > 5);
|
||||
|
||||
path += dir_path_len;
|
||||
|
||||
if (dir_path_len > 0 && path[-1] != '/')
|
||||
{
|
||||
*path++ = '/';
|
||||
--remaining;
|
||||
}
|
||||
|
||||
strncpy(path, minidump_desc.path(), remaining);
|
||||
|
||||
LL_INFOS() << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL;
|
||||
LLApp::runErrorHandler();
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
clear_signals();
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool unix_post_minidump_callback(const char *dump_dir,
|
||||
const char *minidump_id,
|
||||
void *context, bool succeeded)
|
||||
{
|
||||
// Copy minidump file path into fixed buffer in the app instance to avoid
|
||||
// heap allocations in a crash handler.
|
||||
|
||||
// path format: <dump_dir>/<minidump_id>.dmp
|
||||
int dirPathLength = strlen(dump_dir);
|
||||
int idLength = strlen(minidump_id);
|
||||
|
||||
// The path must not be truncated.
|
||||
llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
|
||||
|
||||
char * path = LLApp::instance()->getMiniDumpFilename();
|
||||
S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
|
||||
strncpy(path, dump_dir, remaining);
|
||||
remaining -= dirPathLength;
|
||||
path += dirPathLength;
|
||||
if (remaining > 0 && dirPathLength > 0 && path[-1] != '/')
|
||||
{
|
||||
*path++ = '/';
|
||||
--remaining;
|
||||
}
|
||||
if (remaining > 0)
|
||||
{
|
||||
strncpy(path, minidump_id, remaining);
|
||||
remaining -= idLength;
|
||||
path += idLength;
|
||||
strncpy(path, ".dmp", remaining);
|
||||
}
|
||||
|
||||
LL_INFOS() << "generated minidump: " << path << LL_ENDL;
|
||||
LLApp::runErrorHandler();
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
clear_signals();
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif // !WINDOWS
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
bool windows_post_minidump_callback(const wchar_t* dump_path,
|
||||
const wchar_t* minidump_id,
|
||||
void* context,
|
||||
EXCEPTION_POINTERS* exinfo,
|
||||
MDRawAssertionInfo* assertion,
|
||||
bool succeeded)
|
||||
{
|
||||
char * path = LLApp::instance()->getMiniDumpFilename();
|
||||
S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
|
||||
size_t bytesUsed;
|
||||
|
||||
bytesUsed = wcstombs(path, dump_path, static_cast<size_t>(remaining));
|
||||
remaining -= bytesUsed;
|
||||
path += bytesUsed;
|
||||
if(remaining > 0 && bytesUsed > 0 && path[-1] != '\\')
|
||||
{
|
||||
*path++ = '\\';
|
||||
--remaining;
|
||||
}
|
||||
if(remaining > 0)
|
||||
{
|
||||
bytesUsed = wcstombs(path, minidump_id, static_cast<size_t>(remaining));
|
||||
remaining -= bytesUsed;
|
||||
path += bytesUsed;
|
||||
}
|
||||
if(remaining > 0)
|
||||
{
|
||||
strncpy(path, ".dmp", remaining);
|
||||
}
|
||||
|
||||
LL_INFOS() << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL;
|
||||
// *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
|
||||
//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK);
|
||||
// *TODO: Translate the signals/exceptions into cross-platform stuff
|
||||
// Windows implementation
|
||||
LL_INFOS() << "Entering Windows Exception Handler..." << LL_ENDL;
|
||||
|
||||
if (LLApp::isError())
|
||||
{
|
||||
LL_WARNS() << "Got another fatal signal while in the error handler, die now!" << LL_ENDL;
|
||||
}
|
||||
|
||||
// Flag status to error, so thread_error starts its work
|
||||
LLApp::setError();
|
||||
|
||||
// Block in the exception handler until the app has stopped
|
||||
// This is pretty sketchy, but appears to work just fine
|
||||
while (!LLApp::isStopped())
|
||||
{
|
||||
ms_sleep(10);
|
||||
}
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -60,10 +60,6 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace google_breakpad {
|
||||
class ExceptionHandler; // See exception_handler.h
|
||||
}
|
||||
|
||||
class LL_COMMON_API LLApp : public LLOptionInterface
|
||||
{
|
||||
friend class LLErrorThread;
|
||||
@@ -233,22 +229,11 @@ public:
|
||||
static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
|
||||
//@}
|
||||
|
||||
// the maximum length of the minidump filename returned by getMiniDumpFilename()
|
||||
static const U32 MAX_MINDUMP_PATH_LENGTH = 256;
|
||||
|
||||
// change the directory where Breakpad minidump files are written to
|
||||
void setMiniDumpDir(const std::string &path);
|
||||
void setDebugFileNames(const std::string &path);
|
||||
|
||||
// Return the Google Breakpad minidump filename after a crash.
|
||||
char *getMiniDumpFilename() { return mMinidumpPath; }
|
||||
std::string* getStaticDebugFile() { return &mStaticDebugFileName; }
|
||||
std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; }
|
||||
|
||||
// Write out a Google Breakpad minidump file.
|
||||
void writeMiniDump();
|
||||
|
||||
|
||||
#if !LL_WINDOWS
|
||||
//
|
||||
// Child process handling (Unix only for now)
|
||||
@@ -281,8 +266,6 @@ protected:
|
||||
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
|
||||
std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
|
||||
|
||||
std::string mDumpPath; //output path for google breakpad. Dependency workaround.
|
||||
|
||||
#if !LL_WINDOWS
|
||||
static LLAtomicU32* sSigChildCount; // Number of SIGCHLDs received.
|
||||
typedef std::map<pid_t, LLChildInfo> child_map; // Map key is a PID
|
||||
@@ -290,16 +273,13 @@ protected:
|
||||
static LLAppChildCallback sDefaultChildCallback;
|
||||
#endif
|
||||
|
||||
void startErrorThread();
|
||||
|
||||
/**
|
||||
* @brief This method is called at the end, just prior to deinitializing curl.
|
||||
*/
|
||||
void stopErrorThread();
|
||||
|
||||
private:
|
||||
// Contains the filename of the minidump file after a crash.
|
||||
char mMinidumpPath[MAX_MINDUMP_PATH_LENGTH];
|
||||
void startErrorThread();
|
||||
|
||||
std::string mStaticDebugFileName;
|
||||
std::string mDynamicDebugFileName;
|
||||
@@ -323,11 +303,8 @@ private:
|
||||
std::vector<LLLiveFile*> mLiveFiles;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// the static application instance if it was created.
|
||||
static LLApp* sApplication;
|
||||
google_breakpad::ExceptionHandler * mExceptionHandler;
|
||||
|
||||
|
||||
#if !LL_WINDOWS
|
||||
friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
|
||||
|
||||
@@ -1338,7 +1338,7 @@ namespace LLError
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
// VC80 was optimizing the error away.
|
||||
// MSVC is optimizing the error away.
|
||||
#pragma optimize("", off)
|
||||
#endif
|
||||
void crashAndLoop(const std::string& message)
|
||||
@@ -1347,9 +1347,8 @@ namespace LLError
|
||||
DoutFatal(dc::core, message);
|
||||
#else
|
||||
// Now, we go kaboom!
|
||||
int* make_me_crash = NULL;
|
||||
|
||||
*make_me_crash = 0;
|
||||
int* make_me_crash = nullptr;
|
||||
*make_me_crash = 0xDEADBEEF;
|
||||
|
||||
while(true)
|
||||
{
|
||||
|
||||
@@ -281,6 +281,11 @@ int LLFile::rename_nowarn(const std::string& filename, const std::string& newnam
|
||||
int rc = _wrename(utf16filename.c_str(),utf16newname.c_str());
|
||||
#else
|
||||
int rc = ::rename(filename.c_str(),newname.c_str());
|
||||
if (rc == -1 && errno == EXDEV)
|
||||
{
|
||||
rc = std::system(("mv '" + filename + "' '" + newname + '\'').data());
|
||||
errno = 0;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -102,39 +102,47 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_f
|
||||
//static
|
||||
void LLMemory::updateMemoryInfo()
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
HANDLE self = GetCurrentProcess();
|
||||
PROCESS_MEMORY_COUNTERS counters;
|
||||
|
||||
if (!GetProcessMemoryInfo(self, &counters, sizeof(counters)))
|
||||
#if LL_WINDOWS
|
||||
PROCESS_MEMORY_COUNTERS_EX counters;
|
||||
counters.cb = sizeof(counters);
|
||||
|
||||
if (!GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &counters, sizeof(counters)))
|
||||
{
|
||||
LL_WARNS() << "GetProcessMemoryInfo failed" << LL_ENDL;
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
sAllocatedMemInKB = (U32Bytes)(counters.WorkingSetSize) ;
|
||||
sAllocatedPageSizeInKB = (U32Bytes)(counters.PagefileUsage) ;
|
||||
sAllocatedMemInKB = U64Bytes(counters.WorkingSetSize);
|
||||
sAllocatedPageSizeInKB = (counters.PagefileUsage != 0) ? U64Bytes(counters.PagefileUsage) : U64Bytes(counters.PrivateUsage);
|
||||
|
||||
U32Kilobytes avail_phys, avail_virtual;
|
||||
LLMemoryInfo::getAvailableMemoryKB(avail_phys, avail_virtual) ;
|
||||
sMaxPhysicalMemInKB = llmin(avail_phys + sAllocatedMemInKB, sMaxHeapSizeInKB);
|
||||
|
||||
if(sMaxPhysicalMemInKB > sAllocatedMemInKB)
|
||||
MEMORYSTATUSEX memorystat;
|
||||
memorystat.dwLength = sizeof(memorystat);
|
||||
if (!GlobalMemoryStatusEx(&memorystat))
|
||||
{
|
||||
sAvailPhysicalMemInKB = sMaxPhysicalMemInKB - sAllocatedMemInKB ;
|
||||
LL_WARNS() << "GlobalMemoryStatusEx failed" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
#if (defined(_WIN64) || defined(__amd64__) || defined(__x86_64__))
|
||||
sMaxPhysicalMemInKB = U64Bytes(memorystat.ullTotalPhys);
|
||||
sAvailPhysicalMemInKB = U64Bytes(memorystat.ullAvailPhys);
|
||||
#else
|
||||
sMaxPhysicalMemInKB = llmin(U32Kilobytes(U64Bytes(memorystat.ullTotalPhys)), sMaxHeapSizeInKB);
|
||||
if (sMaxPhysicalMemInKB > sAllocatedMemInKB)
|
||||
{
|
||||
sAvailPhysicalMemInKB = U64Bytes(memorystat.ullAvailPhys);;
|
||||
}
|
||||
else
|
||||
{
|
||||
sAvailPhysicalMemInKB = U32Kilobytes(0);
|
||||
}
|
||||
#else
|
||||
//not valid for other systems for now.
|
||||
sAllocatedMemInKB = (U32Bytes)LLMemory::getCurrentRSS();
|
||||
sMaxPhysicalMemInKB = (U32Bytes)U32_MAX ;
|
||||
sAvailPhysicalMemInKB = (U32Bytes)U32_MAX ;
|
||||
#endif
|
||||
|
||||
return ;
|
||||
#else
|
||||
//not valid for other systems for now.
|
||||
sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS());
|
||||
sMaxPhysicalMemInKB = U64Bytes(U32_MAX);
|
||||
sAvailPhysicalMemInKB = U64Bytes(U32_MAX);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@@ -158,7 +166,7 @@ void* LLMemory::tryToAlloc(void* address, U32 size)
|
||||
return address ;
|
||||
#else
|
||||
return (void*)0x01 ; //skip checking
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//static
|
||||
@@ -233,31 +241,31 @@ bool LLMemory::isMemoryPoolLow()
|
||||
//static
|
||||
U32Kilobytes LLMemory::getAvailableMemKB()
|
||||
{
|
||||
return sAvailPhysicalMemInKB ;
|
||||
return sAvailPhysicalMemInKB;
|
||||
}
|
||||
|
||||
//static
|
||||
U32Kilobytes LLMemory::getMaxMemKB()
|
||||
{
|
||||
return sMaxPhysicalMemInKB ;
|
||||
return sMaxPhysicalMemInKB;
|
||||
}
|
||||
|
||||
//static
|
||||
U32Kilobytes LLMemory::getAllocatedMemKB()
|
||||
{
|
||||
return sAllocatedMemInKB ;
|
||||
return sAllocatedMemInKB;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
|
||||
//static
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
{
|
||||
HANDLE self = GetCurrentProcess();
|
||||
PROCESS_MEMORY_COUNTERS counters;
|
||||
|
||||
if (!GetProcessMemoryInfo(self, &counters, sizeof(counters)))
|
||||
|
||||
if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
|
||||
{
|
||||
LL_WARNS() << "GetProcessMemoryInfo failed" << LL_ENDL;
|
||||
return 0;
|
||||
@@ -266,35 +274,7 @@ U64 LLMemory::getCurrentRSS()
|
||||
return counters.WorkingSetSize;
|
||||
}
|
||||
|
||||
//static
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
PROCESS_MEMORY_COUNTERS pmc ;
|
||||
U32 ret = 0 ;
|
||||
|
||||
if (GetProcessMemoryInfo( GetCurrentProcess(), &pmc, sizeof(pmc)) )
|
||||
{
|
||||
ret = pmc.WorkingSetSize ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
#elif defined(LL_DARWIN)
|
||||
|
||||
/*
|
||||
The API used here is not capable of dealing with 64-bit memory sizes, but is available before 10.4.
|
||||
|
||||
Once we start requiring 10.4, we can use the updated API, which looks like this:
|
||||
|
||||
task_basic_info_64_data_t basicInfo;
|
||||
mach_msg_type_number_t basicInfoCount = TASK_BASIC_INFO_64_COUNT;
|
||||
if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
|
||||
|
||||
Of course, this doesn't gain us anything unless we start building the viewer as a 64-bit executable, since that's the only way
|
||||
for our memory allocation to exceed 2^32.
|
||||
*/
|
||||
|
||||
// if (sysctl(ctl, 2, &page_size, &size, NULL, 0) == -1)
|
||||
// {
|
||||
// LL_WARNS() << "Couldn't get page size" << LL_ENDL;
|
||||
@@ -307,16 +287,15 @@ U32 LLMemory::getWorkingSetSize()
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
{
|
||||
U64 residentSize = 0;
|
||||
task_basic_info_data_t basicInfo;
|
||||
mach_msg_type_number_t basicInfoCount = TASK_BASIC_INFO_COUNT;
|
||||
if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
|
||||
mach_task_basic_info_data_t basicInfo;
|
||||
mach_msg_type_number_t basicInfoCount = MACH_TASK_BASIC_INFO_COUNT;
|
||||
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
|
||||
{
|
||||
residentSize = basicInfo.resident_size;
|
||||
|
||||
// If we ever wanted it, the process virtual size is also available as:
|
||||
// virtualSize = basicInfo.virtual_size;
|
||||
|
||||
// LL_INFOS() << "resident size is " << residentSize << LL_ENDL;
|
||||
// residentSize = basicInfo.resident_size;
|
||||
// Although this method is defined to return the "resident set size,"
|
||||
// in fact what callers want from it is the total virtual memory
|
||||
// consumed by the application.
|
||||
residentSize = basicInfo.virtual_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -326,11 +305,6 @@ U64 LLMemory::getCurrentRSS()
|
||||
return residentSize;
|
||||
}
|
||||
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#elif defined(LL_LINUX)
|
||||
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
@@ -342,7 +316,7 @@ U64 LLMemory::getCurrentRSS()
|
||||
if (fp == NULL)
|
||||
{
|
||||
LL_WARNS() << "couldn't open " << statPath << LL_ENDL;
|
||||
goto bail;
|
||||
return rss;
|
||||
}
|
||||
|
||||
// Eee-yew! See Documentation/filesystems/proc.txt in your
|
||||
@@ -361,49 +335,8 @@ U64 LLMemory::getCurrentRSS()
|
||||
|
||||
fclose(fp);
|
||||
|
||||
bail:
|
||||
return rss;
|
||||
}
|
||||
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#elif LL_SOLARIS
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#define _STRUCTURED_PROC 1
|
||||
#include <sys/procfs.h>
|
||||
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
{
|
||||
char path [LL_MAX_PATH]; /* Flawfinder: ignore */
|
||||
|
||||
sprintf(path, "/proc/%d/psinfo", (int)getpid());
|
||||
int proc_fd = -1;
|
||||
if((proc_fd = open(path, O_RDONLY)) == -1){
|
||||
LL_WARNS() << "LLmemory::getCurrentRSS() unable to open " << path << ". Returning 0 RSS!" << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
psinfo_t proc_psinfo;
|
||||
if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
|
||||
LL_WARNS() << "LLmemory::getCurrentRSS() Unable to read from " << path << ". Returning 0 RSS!" << LL_ENDL;
|
||||
close(proc_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(proc_fd);
|
||||
|
||||
return((U64)proc_psinfo.pr_rssize * 1024);
|
||||
}
|
||||
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
@@ -411,11 +344,6 @@ U64 LLMemory::getCurrentRSS()
|
||||
return 0;
|
||||
}
|
||||
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -427,7 +355,7 @@ LLMemTracker* LLMemTracker::sInstance = NULL ;
|
||||
|
||||
LLMemTracker::LLMemTracker()
|
||||
{
|
||||
mLastAllocatedMem = LLMemory::getWorkingSetSize() ;
|
||||
mLastAllocatedMem = LLMemory::getCurrentRSS() ;
|
||||
mCapacity = 128 ;
|
||||
mCurIndex = 0 ;
|
||||
mCounter = 0 ;
|
||||
@@ -480,7 +408,7 @@ void LLMemTracker::track(const char* function, const int line)
|
||||
return ;
|
||||
}
|
||||
|
||||
U32 allocated_mem = LLMemory::getWorkingSetSize() ;
|
||||
U64 allocated_mem = LLMemory::getCurrentRSS() ;
|
||||
|
||||
LLMutexLock lock(mMutexp) ;
|
||||
|
||||
|
||||
@@ -133,11 +133,15 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
|
||||
#if defined(LL_WINDOWS)
|
||||
return _aligned_malloc(size, align);
|
||||
#else
|
||||
char* aligned = NULL;
|
||||
void* mem = malloc( size + (align - 1) + sizeof(void*) );
|
||||
char* aligned = ((char*)mem) + sizeof(void*);
|
||||
aligned += align - ((uintptr_t)aligned & (align - 1));
|
||||
if (mem)
|
||||
{
|
||||
aligned = ((char*)mem) + sizeof(void*);
|
||||
aligned += align - ((uintptr_t)aligned & (align - 1));
|
||||
|
||||
((void**)aligned)[-1] = mem;
|
||||
((void**)aligned)[-1] = mem;
|
||||
}
|
||||
return aligned;
|
||||
#endif
|
||||
}
|
||||
@@ -365,7 +369,6 @@ public:
|
||||
// Return the resident set size of the current process, in bytes.
|
||||
// Return value is zero if not known.
|
||||
static U64 getCurrentRSS();
|
||||
static U32 getWorkingSetSize();
|
||||
static void* tryToAlloc(void* address, U32 size);
|
||||
static void initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure);
|
||||
static void updateMemoryInfo() ;
|
||||
|
||||
@@ -126,9 +126,9 @@ public:
|
||||
virtual Date asDate() const { return LLDate(); }
|
||||
virtual URI asURI() const { return LLURI(); }
|
||||
virtual const Binary& asBinary() const { static const std::vector<U8> empty; return empty; }
|
||||
|
||||
virtual const String& asStringRef() const { static const std::string empty; return empty; }
|
||||
|
||||
virtual const String& asStringRef() const { static const std::string empty; return empty; }
|
||||
|
||||
virtual bool has(const String&) const { return false; }
|
||||
virtual LLSD get(const String&) const { return LLSD(); }
|
||||
virtual LLSD getKeys() const { return LLSD::emptyArray(); }
|
||||
@@ -183,10 +183,11 @@ namespace
|
||||
public:
|
||||
ImplBase(DataRef value) : mValue(value) { }
|
||||
|
||||
virtual LLSD::Type type() const { return T; }
|
||||
LLSD::Type type() const override { return T; }
|
||||
|
||||
using LLSD::Impl::assign; // Unhiding base class virtuals...
|
||||
virtual void assign(LLSD::Impl*& var, DataRef value) {
|
||||
void assign(LLSD::Impl*& var, DataRef value) override
|
||||
{
|
||||
if (shared())
|
||||
{
|
||||
Impl::assign(var, value);
|
||||
@@ -205,10 +206,10 @@ namespace
|
||||
public:
|
||||
ImplBoolean(LLSD::Boolean v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return mValue; }
|
||||
virtual LLSD::Integer asInteger() const { return mValue ? 1 : 0; }
|
||||
virtual LLSD::Real asReal() const { return mValue ? 1 : 0; }
|
||||
virtual LLSD::String asString() const;
|
||||
LLSD::Boolean asBoolean() const override { return mValue; }
|
||||
LLSD::Integer asInteger() const override { return mValue ? 1 : 0; }
|
||||
LLSD::Real asReal() const override { return mValue ? 1 : 0; }
|
||||
LLSD::String asString() const override;
|
||||
};
|
||||
|
||||
LLSD::String ImplBoolean::asString() const
|
||||
@@ -226,10 +227,10 @@ namespace
|
||||
public:
|
||||
ImplInteger(LLSD::Integer v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return mValue != 0; }
|
||||
virtual LLSD::Integer asInteger() const { return mValue; }
|
||||
virtual LLSD::Real asReal() const { return mValue; }
|
||||
virtual LLSD::String asString() const;
|
||||
LLSD::Boolean asBoolean() const override { return mValue != 0; }
|
||||
LLSD::Integer asInteger() const override { return mValue; }
|
||||
LLSD::Real asReal() const override { return mValue; }
|
||||
LLSD::String asString() const override;
|
||||
};
|
||||
|
||||
LLSD::String ImplInteger::asString() const
|
||||
@@ -242,10 +243,10 @@ namespace
|
||||
public:
|
||||
ImplReal(LLSD::Real v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const;
|
||||
virtual LLSD::Integer asInteger() const;
|
||||
virtual LLSD::Real asReal() const { return mValue; }
|
||||
virtual LLSD::String asString() const;
|
||||
LLSD::Boolean asBoolean() const override;
|
||||
LLSD::Integer asInteger() const override;
|
||||
LLSD::Real asReal() const override { return mValue; }
|
||||
LLSD::String asString() const override;
|
||||
};
|
||||
|
||||
LLSD::Boolean ImplReal::asBoolean() const
|
||||
@@ -264,15 +265,15 @@ namespace
|
||||
public:
|
||||
ImplString(const LLSD::String& v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return !mValue.empty(); }
|
||||
virtual LLSD::Integer asInteger() const;
|
||||
virtual LLSD::Real asReal() const;
|
||||
virtual LLSD::String asString() const { return mValue; }
|
||||
virtual LLSD::UUID asUUID() const { return LLUUID(mValue); }
|
||||
virtual LLSD::Date asDate() const { return LLDate(mValue); }
|
||||
virtual LLSD::URI asURI() const { return LLURI(mValue); }
|
||||
virtual int size() const { return mValue.size(); }
|
||||
virtual const LLSD::String& asStringRef() const { return mValue; }
|
||||
LLSD::Boolean asBoolean() const override { return !mValue.empty(); }
|
||||
LLSD::Integer asInteger() const override;
|
||||
LLSD::Real asReal() const override;
|
||||
LLSD::String asString() const override { return mValue; }
|
||||
LLSD::UUID asUUID() const override { return LLUUID(mValue); }
|
||||
LLSD::Date asDate() const override { return LLDate(mValue); }
|
||||
LLSD::URI asURI() const override { return LLURI(mValue); }
|
||||
int size() const override { return mValue.size(); }
|
||||
const LLSD::String& asStringRef() const override { return mValue; }
|
||||
};
|
||||
|
||||
LLSD::Integer ImplString::asInteger() const
|
||||
@@ -308,8 +309,8 @@ namespace
|
||||
public:
|
||||
ImplUUID(const LLSD::UUID& v) : Base(v) { }
|
||||
|
||||
virtual LLSD::String asString() const{ return mValue.asString(); }
|
||||
virtual LLSD::UUID asUUID() const { return mValue; }
|
||||
LLSD::String asString() const override { return mValue.asString(); }
|
||||
LLSD::UUID asUUID() const override { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -321,16 +322,17 @@ namespace
|
||||
: ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>(v)
|
||||
{ }
|
||||
|
||||
virtual LLSD::Integer asInteger() const
|
||||
LLSD::Integer asInteger() const override
|
||||
{
|
||||
return (LLSD::Integer)(mValue.secondsSinceEpoch());
|
||||
}
|
||||
virtual LLSD::Real asReal() const
|
||||
LLSD::Real asReal() const override
|
||||
{
|
||||
return mValue.secondsSinceEpoch();
|
||||
}
|
||||
virtual LLSD::String asString() const{ return mValue.asString(); }
|
||||
virtual LLSD::Date asDate() const { return mValue; }
|
||||
|
||||
LLSD::String asString() const override { return mValue.asString(); }
|
||||
LLSD::Date asDate() const override { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -340,8 +342,8 @@ namespace
|
||||
public:
|
||||
ImplURI(const LLSD::URI& v) : Base(v) { }
|
||||
|
||||
virtual LLSD::String asString() const{ return mValue.asString(); }
|
||||
virtual LLSD::URI asURI() const { return mValue; }
|
||||
LLSD::String asString() const override { return mValue.asString(); }
|
||||
LLSD::URI asURI() const override { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -351,7 +353,7 @@ namespace
|
||||
public:
|
||||
ImplBinary(const LLSD::Binary& v) : Base(v) { }
|
||||
|
||||
virtual const LLSD::Binary& asBinary() const{ return mValue; }
|
||||
const LLSD::Binary& asBinary() const override { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -368,33 +370,33 @@ namespace
|
||||
public:
|
||||
ImplMap() { }
|
||||
|
||||
virtual ImplMap& makeMap(LLSD::Impl*&);
|
||||
ImplMap& makeMap(LLSD::Impl*&) override;
|
||||
|
||||
virtual LLSD::Type type() const { return LLSD::TypeMap; }
|
||||
LLSD::Type type() const override { return LLSD::TypeMap; }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
|
||||
LLSD::Boolean asBoolean() const override { return !mData.empty(); }
|
||||
|
||||
virtual bool has(const LLSD::String&) const;
|
||||
bool has(const LLSD::String&) const override;
|
||||
|
||||
using LLSD::Impl::get; // Unhiding get(LLSD::Integer)
|
||||
using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer)
|
||||
using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer)
|
||||
virtual LLSD get(const LLSD::String&) const;
|
||||
virtual LLSD getKeys() const;
|
||||
LLSD get(const LLSD::String&) const override;
|
||||
LLSD getKeys() const override;
|
||||
void insert(const LLSD::String& k, const LLSD& v);
|
||||
virtual void erase(const LLSD::String&);
|
||||
void erase(const LLSD::String&) override;
|
||||
LLSD& ref(const LLSD::String&);
|
||||
virtual const LLSD& ref(const LLSD::String&) const;
|
||||
const LLSD& ref(const LLSD::String&) const override;
|
||||
|
||||
virtual int size() const { return mData.size(); }
|
||||
int size() const override { return mData.size(); }
|
||||
|
||||
LLSD::map_iterator beginMap() { return mData.begin(); }
|
||||
LLSD::map_iterator endMap() { return mData.end(); }
|
||||
virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
|
||||
virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
|
||||
LLSD::map_const_iterator beginMap() const override { return mData.begin(); }
|
||||
LLSD::map_const_iterator endMap() const override { return mData.end(); }
|
||||
|
||||
virtual void dumpStats() const;
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
void dumpStats() const override;
|
||||
void calcStats(S32 type_counts[], S32 share_counts[]) const override;
|
||||
};
|
||||
|
||||
ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
|
||||
@@ -481,7 +483,7 @@ namespace
|
||||
{
|
||||
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
|
||||
Impl::calcStats((*iter).second, type_counts, share_counts);
|
||||
iter++;
|
||||
++iter;
|
||||
}
|
||||
|
||||
// Add in the values for this map
|
||||
@@ -502,32 +504,32 @@ namespace
|
||||
public:
|
||||
ImplArray() { }
|
||||
|
||||
virtual ImplArray& makeArray(Impl*&);
|
||||
ImplArray& makeArray(Impl*&) override;
|
||||
|
||||
virtual LLSD::Type type() const { return LLSD::TypeArray; }
|
||||
LLSD::Type type() const override { return LLSD::TypeArray; }
|
||||
|
||||
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
|
||||
LLSD::Boolean asBoolean() const override { return !mData.empty(); }
|
||||
|
||||
using LLSD::Impl::get; // Unhiding get(LLSD::String)
|
||||
using LLSD::Impl::erase; // Unhiding erase(LLSD::String)
|
||||
using LLSD::Impl::ref; // Unhiding ref(LLSD::String)
|
||||
virtual int size() const;
|
||||
virtual LLSD get(LLSD::Integer) const;
|
||||
int size() const override;
|
||||
LLSD get(LLSD::Integer) const override;
|
||||
void set(LLSD::Integer, const LLSD&);
|
||||
void insert(LLSD::Integer, const LLSD&);
|
||||
LLSD& append(const LLSD&);
|
||||
virtual void erase(LLSD::Integer);
|
||||
void erase(LLSD::Integer) override;
|
||||
LLSD& ref(LLSD::Integer);
|
||||
virtual const LLSD& ref(LLSD::Integer) const;
|
||||
const LLSD& ref(LLSD::Integer) const override;
|
||||
|
||||
LLSD::array_iterator beginArray() { return mData.begin(); }
|
||||
LLSD::array_iterator endArray() { return mData.end(); }
|
||||
LLSD::reverse_array_iterator rbeginArray() { return mData.rbegin(); }
|
||||
LLSD::reverse_array_iterator rendArray() { return mData.rend(); }
|
||||
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
|
||||
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
|
||||
LLSD::array_const_iterator beginArray() const override { return mData.begin(); }
|
||||
LLSD::array_const_iterator endArray() const override { return mData.end(); }
|
||||
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
void calcStats(S32 type_counts[], S32 share_counts[]) const override;
|
||||
};
|
||||
|
||||
ImplArray& ImplArray::makeArray(Impl*& var)
|
||||
@@ -631,7 +633,7 @@ namespace
|
||||
while (iter != endArray())
|
||||
{ // Add values for all items held in the array
|
||||
Impl::calcStats((*iter), type_counts, share_counts);
|
||||
iter++;
|
||||
++iter;
|
||||
}
|
||||
|
||||
// Add in the values for this array
|
||||
@@ -703,7 +705,7 @@ void LLSD::Impl::assign(Impl*& var, const Impl* other)
|
||||
|
||||
void LLSD::Impl::assignUndefined(Impl*& var)
|
||||
{
|
||||
reset(var, 0);
|
||||
reset(var, nullptr);
|
||||
}
|
||||
|
||||
void LLSD::Impl::assign(Impl*& var, LLSD::Boolean v)
|
||||
@@ -779,7 +781,7 @@ void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const
|
||||
S32 tp = S32(type());
|
||||
if (0 <= tp && tp < LLSD::TypeLLSDNumTypes)
|
||||
{
|
||||
type_counts[tp]++;
|
||||
type_counts[tp]++;
|
||||
if (shared())
|
||||
{
|
||||
share_counts[tp]++;
|
||||
@@ -813,10 +815,10 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; }
|
||||
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); }
|
||||
LLSD::LLSD() : impl(nullptr) { ALLOC_LLSD_OBJECT; }
|
||||
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, nullptr); }
|
||||
|
||||
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
|
||||
LLSD::LLSD(const LLSD& other) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(other); }
|
||||
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
|
||||
|
||||
|
||||
@@ -825,17 +827,17 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
|
||||
LLSD::Type LLSD::type() const { return safe(impl).type(); }
|
||||
|
||||
// Scalar Constructors
|
||||
LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Boolean v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Integer v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Real v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const UUID& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const String& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Date& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const URI& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Binary& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
|
||||
// Convenience Constructors
|
||||
LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); }
|
||||
LLSD::LLSD(F32 v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign((Real)v); }
|
||||
|
||||
// Scalar Assignment
|
||||
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
|
||||
@@ -860,7 +862,7 @@ const LLSD::Binary& LLSD::asBinary() const { return safe(impl).asBinary(); }
|
||||
const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }
|
||||
|
||||
// const char * helpers
|
||||
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const char* v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
void LLSD::assign(const char* v)
|
||||
{
|
||||
if(v) assign(std::string(v));
|
||||
@@ -927,7 +929,7 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
|
||||
// sStorage will point to the result of the last call. This will actually
|
||||
// be one leak, but since this is used only when running under the
|
||||
// debugger, it should not be an issue.
|
||||
static char *sStorage = NULL;
|
||||
static char *sStorage = nullptr;
|
||||
delete[] sStorage;
|
||||
std::string out_string;
|
||||
{
|
||||
|
||||
@@ -385,9 +385,9 @@ public:
|
||||
using an arbitrary pointer or scalar type to std::string.
|
||||
*/
|
||||
//@{
|
||||
LLSD(const void*); ///< construct from aribrary pointers
|
||||
void assign(const void*); ///< assign from arbitrary pointers
|
||||
LLSD& operator=(const void*); ///< assign from arbitrary pointers
|
||||
LLSD(const void*) = delete; ///< construct from aribrary pointers
|
||||
void assign(const void*) = delete; ///< assign from arbitrary pointers
|
||||
LLSD& operator=(const void*) = delete; ///< assign from arbitrary pointers
|
||||
|
||||
bool has(Integer) const; ///< has() only works for Maps
|
||||
//@}
|
||||
|
||||
@@ -79,6 +79,17 @@ LLSD LlsdFromJson(const nlohmann::json &val)
|
||||
return result;
|
||||
}
|
||||
|
||||
LLSD LlsdFromJsonString(const std::string& str)
|
||||
{
|
||||
auto json = nlohmann::json::parse(str, nullptr, false);
|
||||
if (json.is_discarded())
|
||||
{
|
||||
LL_WARNS() << "Cannot parse invalid json string:\n" << str << LL_ENDL;
|
||||
return LLSD();
|
||||
}
|
||||
return LlsdFromJson(json);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
nlohmann::json LlsdToJson(const LLSD &val)
|
||||
{
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
/// For maps and arrays child entries will be converted and added to the structure.
|
||||
/// Order is preserved for an array but not for objects.
|
||||
LLSD LlsdFromJson(const nlohmann::json &val);
|
||||
LLSD LlsdFromJsonString(const std::string& body);
|
||||
|
||||
/// Convert an LLSD object into Parsed JSON object maintaining member names and
|
||||
/// array indexs.
|
||||
|
||||
@@ -118,7 +118,7 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
|
||||
fail_if_not_legacy = true;
|
||||
}
|
||||
|
||||
if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */
|
||||
if (!strnicmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */
|
||||
{
|
||||
legacy_no_header = true;
|
||||
inbuf = (int)str.gcount();
|
||||
@@ -141,9 +141,8 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
|
||||
}
|
||||
header = hdr_buf;
|
||||
|
||||
std::string::size_type start = std::string::npos;
|
||||
std::string::size_type start = header.find_first_not_of("<? ");
|
||||
std::string::size_type end = std::string::npos;
|
||||
start = header.find_first_not_of("<? ");
|
||||
if (start != std::string::npos)
|
||||
{
|
||||
end = header.find_first_of(" ?", start);
|
||||
@@ -1304,8 +1303,8 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32
|
||||
}
|
||||
|
||||
bool need_comma = false;
|
||||
LLSD::map_const_iterator iter = data.beginMap();
|
||||
LLSD::map_const_iterator end = data.endMap();
|
||||
auto iter = data.beginMap();
|
||||
auto end = data.endMap();
|
||||
for(; iter != end; ++iter)
|
||||
{
|
||||
if(need_comma) ostr << ",";
|
||||
@@ -1323,8 +1322,8 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32
|
||||
{
|
||||
ostr << post << pre << "[";
|
||||
bool need_comma = false;
|
||||
LLSD::array_const_iterator iter = data.beginArray();
|
||||
LLSD::array_const_iterator end = data.endArray();
|
||||
auto iter = data.beginArray();
|
||||
auto end = data.endArray();
|
||||
for(; iter != end; ++iter)
|
||||
{
|
||||
if(need_comma) ostr << ",";
|
||||
@@ -1392,22 +1391,22 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32
|
||||
// *FIX: memory inefficient.
|
||||
const std::vector<U8>& buffer = data.asBinary();
|
||||
ostr << "b(" << buffer.size() << ")\"";
|
||||
if(buffer.size())
|
||||
if(!buffer.empty())
|
||||
{
|
||||
if (options & LLSDFormatter::OPTIONS_PRETTY_BINARY)
|
||||
{
|
||||
std::ios_base::fmtflags old_flags = ostr.flags();
|
||||
ostr.setf( std::ios::hex, std::ios::basefield );
|
||||
ostr << "0x";
|
||||
for (size_t i = 0; i < buffer.size(); i++)
|
||||
for (unsigned char i : buffer)
|
||||
{
|
||||
ostr << (int) buffer[i];
|
||||
ostr << static_cast<int>(i);
|
||||
}
|
||||
ostr.flags(old_flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
ostr.write((const char*)&buffer[0], buffer.size());
|
||||
ostr.write(reinterpret_cast<const char*>(&buffer[0]), buffer.size());
|
||||
}
|
||||
}
|
||||
ostr << "\"";
|
||||
@@ -1444,9 +1443,9 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
|
||||
{
|
||||
ostr.put('{');
|
||||
U32 size_nbo = htonl(data.size());
|
||||
ostr.write((const char*)(&size_nbo), sizeof(U32));
|
||||
LLSD::map_const_iterator iter = data.beginMap();
|
||||
LLSD::map_const_iterator end = data.endMap();
|
||||
ostr.write(reinterpret_cast<const char*>(&size_nbo), sizeof(U32));
|
||||
auto iter = data.beginMap();
|
||||
auto end = data.endMap();
|
||||
for(; iter != end; ++iter)
|
||||
{
|
||||
ostr.put('k');
|
||||
@@ -1461,9 +1460,9 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
|
||||
{
|
||||
ostr.put('[');
|
||||
U32 size_nbo = htonl(data.size());
|
||||
ostr.write((const char*)(&size_nbo), sizeof(U32));
|
||||
LLSD::array_const_iterator iter = data.beginArray();
|
||||
LLSD::array_const_iterator end = data.endArray();
|
||||
ostr.write(reinterpret_cast<const char*>(&size_nbo), sizeof(U32));
|
||||
auto iter = data.beginArray();
|
||||
auto end = data.endArray();
|
||||
for(; iter != end; ++iter)
|
||||
{
|
||||
format_count += format(*iter, ostr);
|
||||
@@ -1529,7 +1528,7 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
|
||||
const std::vector<U8>& buffer = data.asBinary();
|
||||
U32 size_nbo = htonl(buffer.size());
|
||||
ostr.write((const char*)(&size_nbo), sizeof(U32));
|
||||
if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
|
||||
if(!buffer.empty()) ostr.write((const char*)&buffer[0], buffer.size());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1706,12 +1705,12 @@ int deserialize_string_raw(
|
||||
// *FIX: This is memory inefficient.
|
||||
S32 len = strtol(buf + 1, NULL, 0);
|
||||
if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE;
|
||||
std::vector<char> buf;
|
||||
std::vector<char> buf2;
|
||||
if(len)
|
||||
{
|
||||
buf.resize(len);
|
||||
count += (int)fullread(istr, (char *)&buf[0], len);
|
||||
value.assign(buf.begin(), buf.end());
|
||||
buf2.resize(len);
|
||||
count += (int)fullread(istr, (char *)&buf2[0], len);
|
||||
value.assign(buf2.begin(), buf2.end());
|
||||
}
|
||||
c = istr.get();
|
||||
++count;
|
||||
@@ -2095,7 +2094,18 @@ std::string zip_llsd(LLSD& data)
|
||||
}
|
||||
|
||||
have = CHUNK-strm.avail_out;
|
||||
output = (U8*) realloc(output, cur_size+have);
|
||||
U8* new_output = (U8*) realloc(output, cur_size+have);
|
||||
if (new_output == NULL)
|
||||
{
|
||||
LL_WARNS() << "Failed to compress LLSD block: can't reallocate memory, current size: " << cur_size << " bytes; requested " << cur_size + have << " bytes." << LL_ENDL;
|
||||
deflateEnd(&strm);
|
||||
if (output)
|
||||
{
|
||||
free(output);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
output = new_output;
|
||||
memcpy(output+cur_size, out, have);
|
||||
cur_size += have;
|
||||
}
|
||||
@@ -2114,15 +2124,6 @@ std::string zip_llsd(LLSD& data)
|
||||
deflateEnd(&strm);
|
||||
free(output);
|
||||
|
||||
#if 0 //verify results work with unzip_llsd
|
||||
std::istringstream test(result);
|
||||
LLSD test_sd;
|
||||
if (!unzip_llsd(test_sd, test, result.size()))
|
||||
{
|
||||
LL_ERRS() << "Invalid compression result!" << LL_ENDL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2173,7 +2174,19 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
|
||||
|
||||
U32 have = CHUNK-strm.avail_out;
|
||||
|
||||
result = (U8*) realloc(result, cur_size + have);
|
||||
U8* new_result = (U8*)realloc(result, cur_size + have);
|
||||
if (new_result == NULL)
|
||||
{
|
||||
LL_WARNS() << "Failed to unzip LLSD block: can't reallocate memory, current size: " << cur_size << " bytes; requested " << cur_size + have << " bytes." << LL_ENDL;
|
||||
inflateEnd(&strm);
|
||||
if (result)
|
||||
{
|
||||
free(result);
|
||||
}
|
||||
delete in;
|
||||
return false;
|
||||
}
|
||||
result = new_result;
|
||||
memcpy(result+cur_size, out, have);
|
||||
cur_size += have;
|
||||
|
||||
@@ -2219,6 +2232,11 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
|
||||
//and trailers are different for the formats.
|
||||
U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size )
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
LL_WARNS() << "No data to unzip." << LL_ENDL;
|
||||
return NULL;
|
||||
}
|
||||
U8* result = NULL;
|
||||
U32 cur_size = 0;
|
||||
z_stream strm;
|
||||
@@ -2258,7 +2276,23 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
|
||||
}
|
||||
U32 have = CHUNK-strm.avail_out;
|
||||
|
||||
result = (U8*) realloc(result, cur_size + have);
|
||||
U8* new_result = (U8*) realloc(result, cur_size + have);
|
||||
if (new_result == NULL)
|
||||
{
|
||||
LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size
|
||||
<< " bytes; requested " << cur_size + have
|
||||
<< " bytes; total syze: ." << size << " bytes."
|
||||
<< LL_ENDL;
|
||||
inflateEnd(&strm);
|
||||
if (result)
|
||||
{
|
||||
free(result);
|
||||
}
|
||||
delete [] in;
|
||||
valid = false;
|
||||
return NULL;
|
||||
}
|
||||
result = new_result;
|
||||
memcpy(result+cur_size, out, have);
|
||||
cur_size += have;
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ bool skip_to_end_of_next_keyword(const char* keyword, std::istream& input_stream
|
||||
}
|
||||
else
|
||||
{
|
||||
int key_index = 1;
|
||||
size_t key_index = 1;
|
||||
while ( key_index < key_length
|
||||
&& keyword[key_index - 1] == c
|
||||
&& input_stream.good())
|
||||
|
||||
@@ -577,7 +577,7 @@ std::string utf8str_truncate(const std::string& utf8str, const S32 max_len)
|
||||
}
|
||||
|
||||
// [RLVa:KB] - Checked: RLVa-2.1.0
|
||||
std::string utf8str_substr(const std::string& utf8str, const S32 index, const S32 max_len)
|
||||
std::string utf8str_substr(const std::string& utf8str, const size_t index, const size_t max_len)
|
||||
{
|
||||
if (0 == max_len)
|
||||
{
|
||||
@@ -589,7 +589,7 @@ std::string utf8str_substr(const std::string& utf8str, const S32 index, const S3
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 cur_char = max_len;
|
||||
size_t cur_char = max_len;
|
||||
|
||||
// If we're ASCII, we don't need to do anything
|
||||
if ((U8)utf8str[index + cur_char] > 0x7f)
|
||||
@@ -648,7 +648,7 @@ void utf8str_split(std::list<std::string>& split_list, const std::string& utf8st
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len)
|
||||
std::string utf8str_symbol_truncate(const std::string& utf8str, const size_t symbol_len)
|
||||
{
|
||||
if (0 == symbol_len)
|
||||
{
|
||||
@@ -660,7 +660,7 @@ std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = 0, byteIndex = 0;
|
||||
size_t len = 0, byteIndex = 0;
|
||||
const char* aStr = utf8str.c_str();
|
||||
size_t origSize = utf8str.size();
|
||||
|
||||
|
||||
@@ -702,28 +702,10 @@ LLMemoryInfo::LLMemoryInfo()
|
||||
refresh();
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
static U32Kilobytes LLMemoryAdjustKBResult(U32Kilobytes inKB)
|
||||
{
|
||||
// Moved this here from llfloaterabout.cpp
|
||||
|
||||
//! \bug
|
||||
// For some reason, the reported amount of memory is always wrong.
|
||||
// The original adjustment assumes it's always off by one meg, however
|
||||
// errors of as much as 2520 KB have been observed in the value
|
||||
// returned from the GetMemoryStatusEx function. Here we keep the
|
||||
// original adjustment from llfoaterabout.cpp until this can be
|
||||
// fixed somehow.
|
||||
inKB += U32Megabytes(1);
|
||||
|
||||
return inKB;
|
||||
}
|
||||
#endif
|
||||
|
||||
U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
return LLMemoryAdjustKBResult(U32Kilobytes(mStatsMap["Total Physical KB"].asInteger()));
|
||||
return U32Kilobytes(mStatsMap["Total Physical KB"].asInteger());
|
||||
|
||||
#elif LL_DARWIN
|
||||
// This might work on Linux as well. Someone check...
|
||||
@@ -740,43 +722,22 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
|
||||
phys = (U64)(getpagesize()) * (U64)(get_phys_pages());
|
||||
return U64Bytes(phys);
|
||||
|
||||
#elif LL_SOLARIS
|
||||
U64 phys = 0;
|
||||
phys = (U64)(getpagesize()) * (U64)(sysconf(_SC_PHYS_PAGES));
|
||||
return U64Bytes(phys);
|
||||
|
||||
#else
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
U32Bytes LLMemoryInfo::getPhysicalMemoryClamped() const
|
||||
{
|
||||
// Return the total physical memory in bytes, but clamp it
|
||||
// to no more than U32_MAX
|
||||
|
||||
U32Kilobytes phys_kb = getPhysicalMemoryKB();
|
||||
if (phys_kb >= U32Gigabytes(4))
|
||||
{
|
||||
return U32Bytes(U32_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
return phys_kb;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// Sigh, this shouldn't be a static method, then we wouldn't have to
|
||||
// reload this data separately from refresh()
|
||||
LLSD statsMap(loadStatsMap());
|
||||
MEMORYSTATUSEX state;
|
||||
state.dwLength = sizeof(state);
|
||||
GlobalMemoryStatusEx(&state);
|
||||
|
||||
avail_physical_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
|
||||
avail_virtual_mem_kb = (U32Kilobytes)statsMap["Avail Virtual KB"].asInteger();
|
||||
avail_physical_mem_kb = U64Bytes(state.ullAvailPhys);
|
||||
avail_virtual_mem_kb = U64Bytes(state.ullAvailVirtual);
|
||||
|
||||
#elif LL_DARWIN
|
||||
// mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
|
||||
@@ -924,7 +885,7 @@ LLSD LLMemoryInfo::loadStatsMap()
|
||||
|
||||
DWORDLONG div = 1024;
|
||||
|
||||
stats.add("Percent Memory use", state.dwMemoryLoad/div);
|
||||
stats.add("Percent Memory use", state.dwMemoryLoad);
|
||||
stats.add("Total Physical KB", state.ullTotalPhys/div);
|
||||
stats.add("Avail Physical KB", state.ullAvailPhys/div);
|
||||
stats.add("Total page KB", state.ullTotalPageFile/div);
|
||||
@@ -973,27 +934,33 @@ LLSD LLMemoryInfo::loadStatsMap()
|
||||
stats.add("PrivateUsage KB", pmem.PrivateUsage/div);
|
||||
|
||||
#elif LL_DARWIN
|
||||
|
||||
const vm_size_t pagekb(vm_page_size / 1024);
|
||||
vm_size_t page_size_kb;
|
||||
if (host_page_size(mach_host_self(), &page_size_kb) != KERN_SUCCESS)
|
||||
{
|
||||
LL_WARNS() << "Unable to get host page size. Using default value." << LL_ENDL;
|
||||
page_size_kb = 4096;
|
||||
}
|
||||
|
||||
page_size_kb = page_size_kb / 1024;
|
||||
|
||||
//
|
||||
// Collect the vm_stat's
|
||||
//
|
||||
|
||||
{
|
||||
vm_statistics_data_t vmstat;
|
||||
mach_msg_type_number_t vmstatCount = HOST_VM_INFO_COUNT;
|
||||
vm_statistics64_data_t vmstat;
|
||||
mach_msg_type_number_t vmstatCount = HOST_VM_INFO64_COUNT;
|
||||
|
||||
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t) &vmstat, &vmstatCount) != KERN_SUCCESS)
|
||||
if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) &vmstat, &vmstatCount) != KERN_SUCCESS)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect memory information" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.add("Pages free KB", pagekb * vmstat.free_count);
|
||||
stats.add("Pages active KB", pagekb * vmstat.active_count);
|
||||
stats.add("Pages inactive KB", pagekb * vmstat.inactive_count);
|
||||
stats.add("Pages wired KB", pagekb * vmstat.wire_count);
|
||||
stats.add("Pages free KB", page_size_kb * vmstat.free_count);
|
||||
stats.add("Pages active KB", page_size_kb * vmstat.active_count);
|
||||
stats.add("Pages inactive KB", page_size_kb * vmstat.inactive_count);
|
||||
stats.add("Pages wired KB", page_size_kb * vmstat.wire_count);
|
||||
|
||||
stats.add("Pages zero fill", vmstat.zero_fill_count);
|
||||
stats.add("Page reactivations", vmstat.reactivations);
|
||||
@@ -1042,20 +1009,20 @@ LLSD LLMemoryInfo::loadStatsMap()
|
||||
//
|
||||
|
||||
{
|
||||
task_basic_info_64_data_t taskinfo;
|
||||
unsigned taskinfoSize = sizeof(taskinfo);
|
||||
|
||||
if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t) &taskinfo, &taskinfoSize) != KERN_SUCCESS)
|
||||
mach_task_basic_info_data_t taskinfo;
|
||||
mach_msg_type_number_t task_count = MACH_TASK_BASIC_INFO_COUNT;
|
||||
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t) &taskinfo, &task_count) != KERN_SUCCESS)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect task information" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.add("Basic suspend count", taskinfo.suspend_count);
|
||||
stats.add("Basic virtual memory KB", taskinfo.virtual_size / 1024);
|
||||
stats.add("Basic resident memory KB", taskinfo.resident_size / 1024);
|
||||
stats.add("Basic new thread policy", taskinfo.policy);
|
||||
}
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect task information" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.add("Basic virtual memory KB", taskinfo.virtual_size / 1024);
|
||||
stats.add("Basic resident memory KB", taskinfo.resident_size / 1024);
|
||||
stats.add("Basic max resident memory KB", taskinfo.resident_size_max / 1024);
|
||||
stats.add("Basic new thread policy", taskinfo.policy);
|
||||
stats.add("Basic suspend count", taskinfo.suspend_count);
|
||||
}
|
||||
}
|
||||
|
||||
#elif LL_SOLARIS
|
||||
|
||||
@@ -114,11 +114,6 @@ public:
|
||||
|
||||
U32Kilobytes getPhysicalMemoryKB() const;
|
||||
|
||||
/*! Memory size in bytes, if total memory is >= 4GB then U32_MAX will
|
||||
** be returned.
|
||||
*/
|
||||
U32Bytes getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes
|
||||
|
||||
//get the available memory infomation in KiloBytes.
|
||||
static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb);
|
||||
|
||||
|
||||
@@ -1165,8 +1165,10 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
||||
// mType, these are the two asset types that are IT_WEARABLE:
|
||||
static U32 AT_BODYPART = 13; // LLAssetType::AT_BODYPART
|
||||
// Viewer local values:
|
||||
static U32 WT_UNKNOWN = 16; // LLWearableType::WT_UNKNOWN
|
||||
static U32 WT_COUNT = 17; // LLWearableType::WT_COUNT
|
||||
static U32 WT_UNKNOWN = 17; // LLWearableType::WT_UNKNOWN
|
||||
static U32 WT_COUNT = 18; // LLWearableType::WT_COUNT
|
||||
// Keep WT_UNKNOWN and WT_COUNT
|
||||
// in sync with llwearabletype.h
|
||||
// The last 8 bits of mFlags contain the wearable type.
|
||||
static U32 II_FLAGS_SUBTYPE_MASK = 0xff; // LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ public:
|
||||
ICONNAME_CLOTHING_SKIRT,
|
||||
ICONNAME_CLOTHING_ALPHA,
|
||||
ICONNAME_CLOTHING_TATTOO,
|
||||
ICONNAME_CLOTHING_UNIVERSAL,
|
||||
|
||||
ICONNAME_ANIMATION,
|
||||
ICONNAME_GESTURE,
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "llsdutil_math.h"
|
||||
#include "message.h"
|
||||
#include "u64.h"
|
||||
#include "llregionflags.h"
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
|
||||
static const F32 SOME_BIG_NUMBER = 1000.0f;
|
||||
static const F32 SOME_BIG_NEG_NUMBER = -1000.0f;
|
||||
@@ -742,8 +744,8 @@ void LLParcel::unpackMessage(LLMessageSystem* msg)
|
||||
void LLParcel::packAccessEntries(LLMessageSystem* msg,
|
||||
const std::map<LLUUID,LLAccessEntry>& list)
|
||||
{
|
||||
access_map_const_iterator cit = list.begin();
|
||||
access_map_const_iterator end = list.end();
|
||||
LLAccessEntry::map::const_iterator cit = list.begin();
|
||||
LLAccessEntry::map::const_iterator end = list.end();
|
||||
|
||||
if (cit == end)
|
||||
{
|
||||
@@ -794,9 +796,28 @@ void LLParcel::unpackAccessEntries(LLMessageSystem* msg,
|
||||
}
|
||||
|
||||
|
||||
void LLParcel::unpackExperienceEntries(LLMessageSystem* msg, U32 type)
|
||||
{
|
||||
LLUUID id;
|
||||
|
||||
S32 i;
|
||||
S32 count = msg->getNumberOfBlocksFast(_PREHASH_List);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i);
|
||||
|
||||
if (id.notNull())
|
||||
{
|
||||
mExperienceKeys[id] = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLParcel::expirePasses(S32 now)
|
||||
{
|
||||
access_map_iterator itor = mAccessList.begin();
|
||||
LLAccessEntry::map::iterator itor = mAccessList.begin();
|
||||
while (itor != mAccessList.end())
|
||||
{
|
||||
const LLAccessEntry& entry = (*itor).second;
|
||||
@@ -886,7 +907,7 @@ BOOL LLParcel::addToAccessList(const LLUUID& agent_id, S32 time)
|
||||
// Can't add owner to these lists
|
||||
return FALSE;
|
||||
}
|
||||
access_map_iterator itor = mAccessList.begin();
|
||||
LLAccessEntry::map::iterator itor = mAccessList.begin();
|
||||
while (itor != mAccessList.end())
|
||||
{
|
||||
const LLAccessEntry& entry = (*itor).second;
|
||||
@@ -931,7 +952,7 @@ BOOL LLParcel::addToBanList(const LLUUID& agent_id, S32 time)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
access_map_iterator itor = mBanList.begin();
|
||||
LLAccessEntry::map::iterator itor = mBanList.begin();
|
||||
while (itor != mBanList.end())
|
||||
{
|
||||
const LLAccessEntry& entry = (*itor).second;
|
||||
@@ -970,7 +991,7 @@ BOOL remove_from_access_array(std::map<LLUUID,LLAccessEntry>* list,
|
||||
const LLUUID& agent_id)
|
||||
{
|
||||
BOOL removed = FALSE;
|
||||
access_map_iterator itor = list->begin();
|
||||
LLAccessEntry::map::iterator itor = list->begin();
|
||||
while (itor != list->end())
|
||||
{
|
||||
const LLAccessEntry& entry = (*itor).second;
|
||||
@@ -1091,7 +1112,7 @@ void LLParcel::startSale(const LLUUID& buyer_id, BOOL is_buyer_group)
|
||||
mSaleTimerExpires.start();
|
||||
mSaleTimerExpires.setTimerExpirySec(U64Microseconds(DEFAULT_USEC_SALE_TIMEOUT));
|
||||
mStatus = OS_LEASE_PENDING;
|
||||
mClaimDate = time(NULL);
|
||||
mClaimDate = time(nullptr);
|
||||
setAuctionID(0);
|
||||
// clear the autoreturn whenever land changes hands
|
||||
setCleanOtherTime(0);
|
||||
@@ -1313,3 +1334,58 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s)
|
||||
// is a distinct option from "None" and "Other"
|
||||
return LLParcel::C_ANY;
|
||||
}
|
||||
|
||||
LLAccessEntry::map LLParcel::getExperienceKeysByType(U32 type) const
|
||||
{
|
||||
LLAccessEntry::map access;
|
||||
LLAccessEntry entry;
|
||||
xp_type_map_t::const_iterator it = mExperienceKeys.begin();
|
||||
for(/**/; it != mExperienceKeys.end(); ++it)
|
||||
{
|
||||
if(it->second == type)
|
||||
{
|
||||
entry.mID = it->first;
|
||||
access[entry.mID] = entry;
|
||||
}
|
||||
}
|
||||
return access;
|
||||
}
|
||||
|
||||
void LLParcel::clearExperienceKeysByType(U32 type)
|
||||
{
|
||||
xp_type_map_t::iterator it = mExperienceKeys.begin();
|
||||
while(it != mExperienceKeys.end())
|
||||
{
|
||||
if(it->second == type)
|
||||
{
|
||||
mExperienceKeys.erase(it++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLParcel::setExperienceKeyType(const LLUUID& experience_key, U32 type)
|
||||
{
|
||||
if (type == EXPERIENCE_KEY_TYPE_NONE)
|
||||
{
|
||||
mExperienceKeys.erase(experience_key);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (countExperienceKeyType(type) < PARCEL_MAX_EXPERIENCE_LIST)
|
||||
{
|
||||
mExperienceKeys[experience_key] = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLParcel::countExperienceKeyType(U32 type)
|
||||
{
|
||||
return std::count_if(
|
||||
boost::begin(mExperienceKeys | boost::adaptors::map_values),
|
||||
boost::end(mExperienceKeys | boost::adaptors::map_values),
|
||||
std::bind2nd(std::equal_to<U32>(), type));
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@ const S32 PARCEL_MAX_ACCESS_LIST = 300;
|
||||
//for access/ban lists.
|
||||
const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f;
|
||||
|
||||
// Maximum number of experiences
|
||||
const S32 PARCEL_MAX_EXPERIENCE_LIST = 24;
|
||||
|
||||
// Weekly charge for listing a parcel in the directory
|
||||
const S32 PARCEL_DIRECTORY_FEE = 30;
|
||||
|
||||
@@ -141,9 +144,11 @@ class LLSD;
|
||||
class LLAccessEntry
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::map<LLUUID,LLAccessEntry> map;
|
||||
|
||||
LLAccessEntry()
|
||||
: mID(),
|
||||
mTime(0),
|
||||
: mTime(0),
|
||||
mFlags(0)
|
||||
{}
|
||||
|
||||
@@ -152,8 +157,6 @@ public:
|
||||
U32 mFlags; // Not used - currently should always be zero
|
||||
};
|
||||
|
||||
typedef std::map<LLUUID,LLAccessEntry>::iterator access_map_iterator;
|
||||
typedef std::map<LLUUID,LLAccessEntry>::const_iterator access_map_const_iterator;
|
||||
|
||||
class LLParcel
|
||||
{
|
||||
@@ -331,6 +334,9 @@ public:
|
||||
void unpackAccessEntries(LLMessageSystem* msg,
|
||||
std::map<LLUUID,LLAccessEntry>* list);
|
||||
|
||||
void unpackExperienceEntries(LLMessageSystem* msg, U32 type);
|
||||
|
||||
|
||||
void setAABBMin(const LLVector3& min) { mAABBMin = min; }
|
||||
void setAABBMax(const LLVector3& max) { mAABBMax = max; }
|
||||
|
||||
@@ -707,6 +713,17 @@ public:
|
||||
std::map<LLUUID,LLAccessEntry> mTempBanList;
|
||||
std::map<LLUUID,LLAccessEntry> mTempAccessList;
|
||||
|
||||
typedef std::map<LLUUID, U32> xp_type_map_t;
|
||||
|
||||
void setExperienceKeyType(const LLUUID& experience_key, U32 type);
|
||||
U32 countExperienceKeyType(U32 type);
|
||||
U32 getExperienceKeyType(const LLUUID& experience_key)const;
|
||||
LLAccessEntry::map getExperienceKeysByType(U32 type)const;
|
||||
void clearExperienceKeysByType(U32 type);
|
||||
|
||||
private:
|
||||
xp_type_map_t mExperienceKeys;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +1,25 @@
|
||||
/**
|
||||
* @file llparcelflags.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -97,8 +91,10 @@ const U32 PF_DEFAULT = PF_ALLOW_FLY
|
||||
| PF_USE_ESTATE_VOICE_CHAN;
|
||||
|
||||
// Access list flags
|
||||
const U32 AL_ACCESS = (1 << 0);
|
||||
const U32 AL_BAN = (1 << 1);
|
||||
const U32 AL_ACCESS = (1 << 0);
|
||||
const U32 AL_BAN = (1 << 1);
|
||||
const U32 AL_ALLOW_EXPERIENCE = (1 << 3);
|
||||
const U32 AL_BLOCK_EXPERIENCE = (1 << 4);
|
||||
//const U32 AL_RENTER = (1 << 2);
|
||||
|
||||
// Block access return values. BA_ALLOWED is the only success case
|
||||
|
||||
@@ -608,7 +608,7 @@ LLSettingsDay::validation_list_t LLSettingsDay::validationList()
|
||||
return validation;
|
||||
}
|
||||
|
||||
LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrack(S32 track)
|
||||
LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrack(size_t track)
|
||||
{
|
||||
static CycleTrack_t emptyTrack;
|
||||
if (mDayTracks.size() <= track)
|
||||
@@ -617,7 +617,7 @@ LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrack(S32 track)
|
||||
return mDayTracks[track];
|
||||
}
|
||||
|
||||
const LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrackConst(S32 track) const
|
||||
const LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrackConst(size_t track) const
|
||||
{
|
||||
static CycleTrack_t emptyTrack;
|
||||
if (mDayTracks.size() <= track)
|
||||
|
||||
@@ -118,8 +118,8 @@ public:
|
||||
virtual LLSettingsWaterPtr_t buildWater(LLSD) const = 0;
|
||||
|
||||
void setInitialized(bool value = true) { mInitialized = value; }
|
||||
CycleTrack_t & getCycleTrack(S32 track);
|
||||
const CycleTrack_t & getCycleTrackConst(S32 track) const;
|
||||
CycleTrack_t & getCycleTrack(size_t track);
|
||||
const CycleTrack_t & getCycleTrackConst(size_t track) const;
|
||||
bool clearCycleTrack(S32 track);
|
||||
bool replaceCycleTrack(S32 track, const CycleTrack_t &source);
|
||||
bool isTrackEmpty(S32 track) const;
|
||||
|
||||
@@ -6331,7 +6331,9 @@ void LLVolumeFace::allocateIndices(S32 num_indices, bool copy)
|
||||
S32 new_size = ((num_indices * sizeof(U16)) + 0xF) & ~0xF;
|
||||
if (copy && num_indices && mIndices && mNumIndices)
|
||||
{
|
||||
#if !LL_USE_TCMALLOC
|
||||
S32 old_size = ((mNumIndices * sizeof(U16)) + 0xF) & ~0xF;
|
||||
#endif
|
||||
|
||||
mIndices = (U16*)ll_aligned_realloc_16(mIndices, new_size, old_size);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ set(llmessage_SOURCE_FILES
|
||||
llclassifiedflags.cpp
|
||||
lldatapacker.cpp
|
||||
lldispatcher.cpp
|
||||
llexperiencecache.cpp
|
||||
llfiltersd2xmlrpc.cpp
|
||||
llhost.cpp
|
||||
llhttpclient.cpp
|
||||
@@ -133,10 +134,12 @@ set(llmessage_HEADER_FILES
|
||||
llcipher.h
|
||||
llcircuit.h
|
||||
llclassifiedflags.h
|
||||
llcororesponder.h
|
||||
llcurl.h
|
||||
lldatapacker.h
|
||||
lldbstrings.h
|
||||
lldispatcher.h
|
||||
llexperiencecache.h
|
||||
lleventflags.h
|
||||
llfiltersd2xmlrpc.h
|
||||
llfollowcamparams.h
|
||||
@@ -227,7 +230,8 @@ target_link_libraries(
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CRYPTO_LIBRARIES}
|
||||
${XMLRPCEPI_LIBRARIES}
|
||||
)
|
||||
${PTHREAD_LIBRARY}
|
||||
)
|
||||
|
||||
# tests
|
||||
if (LL_TESTS)
|
||||
|
||||
@@ -960,5 +960,4 @@ P(webProfileResponders);
|
||||
P(wholeModelFeeResponder);
|
||||
P(wholeModelUploadResponder);
|
||||
P2(XMLRPCResponder, connect_40s);
|
||||
P2(crashLoggerResponder, transfer_300s);
|
||||
P(getUpdateInfoResponder);
|
||||
@@ -139,7 +139,7 @@ void LLAvatarName::fromString(const std::string& full_name)
|
||||
mLegacyLastName = full_name.substr(index+1);
|
||||
if (mLegacyLastName != "Resident")
|
||||
{
|
||||
mUsername = mLegacyFirstName + "." + mLegacyLastName;
|
||||
mUsername = mLegacyFirstName + '.' + mLegacyLastName;
|
||||
mDisplayName = full_name;
|
||||
LLStringUtil::toLower(mUsername);
|
||||
}
|
||||
@@ -184,7 +184,7 @@ std::string LLAvatarName::getCompleteName(bool linefeed) const
|
||||
name = mDisplayName;
|
||||
if (sUseUsernames)
|
||||
{
|
||||
name += (linefeed ? "\n(" : " (") + mUsername + ")";
|
||||
name += (linefeed ? "\n(" : " (") + mUsername + ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,7 +238,7 @@ std::string LLAvatarName::getUserName() const
|
||||
}
|
||||
else
|
||||
{
|
||||
name = mLegacyFirstName + " " + mLegacyLastName;
|
||||
name = mLegacyFirstName + ' ' + mLegacyLastName;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
{
|
||||
case 1 : return getCompleteName();
|
||||
case 2 : return getDisplayName();
|
||||
case 3 : return getLegacyName() + (mIsDisplayNameDefault ? "" : " (" + mDisplayName + ")"); break;
|
||||
case 3 : return getLegacyName() + (mIsDisplayNameDefault ? "" : " (" + mDisplayName + ')'); break;
|
||||
default : return getLegacyName();
|
||||
}
|
||||
}
|
||||
|
||||
43
indra/llmessage/llcororesponder.h
Normal file
43
indra/llmessage/llcororesponder.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file llcororesponder.h
|
||||
* @brief A responder purposed to call coro functions, to ease transition to LLCoro
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
*
|
||||
* Copyright (C) 2020, Liru Færs
|
||||
*
|
||||
* 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 <functional>
|
||||
#include "llhttpclient.h"
|
||||
|
||||
struct LLCoroResponder final : public LLHTTPClient::ResponderWithCompleted
|
||||
{
|
||||
typedef std::function<void(const LLCoroResponder&)> cb_t;
|
||||
LLCoroResponder(const cb_t& cb) : mCB(cb) {}
|
||||
void httpCompleted() override { mCB(*this); }
|
||||
const AIHTTPReceivedHeaders& getHeaders() const { return mReceivedHeaders; }
|
||||
const LLSD& getContent() const { return mContent; }
|
||||
|
||||
char const* getName() const override { return "LLCoroResponder"; }
|
||||
private:
|
||||
const cb_t mCB;
|
||||
};
|
||||
|
||||
928
indra/llmessage/llexperiencecache.cpp
Normal file
928
indra/llmessage/llexperiencecache.cpp
Normal file
@@ -0,0 +1,928 @@
|
||||
/**
|
||||
* @file llexperiencecache.cpp
|
||||
* @brief llexperiencecache and related class definitions
|
||||
*
|
||||
* $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 "llexperiencecache.h"
|
||||
|
||||
#include "llavatarname.h"
|
||||
#include "llcororesponder.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "lleventfilter.h"
|
||||
#include "lldir.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
//=========================================================================
|
||||
namespace LLExperienceCacheImpl
|
||||
{
|
||||
void mapKeys(const LLSD& legacyKeys);
|
||||
F64 getErrorRetryDeltaTime(S32 status, const AIHTTPReceivedHeaders& headers);
|
||||
bool maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age);
|
||||
|
||||
static const std::string PRIVATE_KEY = "private_id";
|
||||
static const std::string EXPERIENCE_ID = "public_id";
|
||||
|
||||
static const std::string MAX_AGE("max-age");
|
||||
static const boost::char_separator<char> EQUALS_SEPARATOR("=");
|
||||
static const boost::char_separator<char> COMMA_SEPARATOR(",");
|
||||
|
||||
// *TODO$: this seems to be tied to mapKeys which is used by bootstrap.... but I don't think that bootstrap is used.
|
||||
typedef std::map<LLUUID, LLUUID> KeyMap;
|
||||
KeyMap privateToPublicKeyMap;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
const std::string LLExperienceCache::PRIVATE_KEY = "private_id";
|
||||
const std::string LLExperienceCache::MISSING = "DoesNotExist";
|
||||
|
||||
const std::string LLExperienceCache::AGENT_ID = "agent_id";
|
||||
const std::string LLExperienceCache::GROUP_ID = "group_id";
|
||||
const std::string LLExperienceCache::EXPERIENCE_ID = "public_id";
|
||||
const std::string LLExperienceCache::NAME = "name";
|
||||
const std::string LLExperienceCache::PROPERTIES = "properties";
|
||||
const std::string LLExperienceCache::EXPIRES = "expiration";
|
||||
const std::string LLExperienceCache::DESCRIPTION = "description";
|
||||
const std::string LLExperienceCache::QUOTA = "quota";
|
||||
const std::string LLExperienceCache::MATURITY = "maturity";
|
||||
const std::string LLExperienceCache::METADATA = "extended_metadata";
|
||||
const std::string LLExperienceCache::SLURL = "slurl";
|
||||
|
||||
// should be in sync with experience-api/experiences/models.py
|
||||
const int LLExperienceCache::PROPERTY_INVALID = 1 << 0;
|
||||
const int LLExperienceCache::PROPERTY_PRIVILEGED = 1 << 3;
|
||||
const int LLExperienceCache::PROPERTY_GRID = 1 << 4;
|
||||
const int LLExperienceCache::PROPERTY_PRIVATE = 1 << 5;
|
||||
const int LLExperienceCache::PROPERTY_DISABLED = 1 << 6;
|
||||
const int LLExperienceCache::PROPERTY_SUSPENDED = 1 << 7;
|
||||
|
||||
// default values
|
||||
const F64 LLExperienceCache::DEFAULT_EXPIRATION = 600.0;
|
||||
const S32 LLExperienceCache::DEFAULT_QUOTA = 128; // this is megabytes
|
||||
const int LLExperienceCache::SEARCH_PAGE_SIZE = 30;
|
||||
|
||||
//=========================================================================
|
||||
LLExperienceCache::LLExperienceCache():
|
||||
mShutdown(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLExperienceCache::~LLExperienceCache()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLExperienceCache::initSingleton()
|
||||
{
|
||||
mCacheFileName = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "experience_cache.xml");
|
||||
|
||||
LL_INFOS("ExperienceCache") << "Loading " << mCacheFileName << LL_ENDL;
|
||||
llifstream cache_stream(mCacheFileName.c_str());
|
||||
|
||||
if (cache_stream.is_open())
|
||||
{
|
||||
cache_stream >> (*this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLExperienceCache::cleanup()
|
||||
{
|
||||
LL_INFOS("ExperienceCache") << "Saving " << mCacheFileName << LL_ENDL;
|
||||
|
||||
llofstream cache_stream(mCacheFileName.c_str());
|
||||
if (cache_stream.is_open())
|
||||
{
|
||||
cache_stream << (*this);
|
||||
}
|
||||
mShutdown = true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::importFile(std::istream& istr)
|
||||
{
|
||||
LLSD data;
|
||||
S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
|
||||
if (parse_count < 1) return;
|
||||
|
||||
LLSD experiences = data["experiences"];
|
||||
|
||||
LLUUID public_key;
|
||||
LLSD::map_const_iterator it = experiences.beginMap();
|
||||
for (; it != experiences.endMap(); ++it)
|
||||
{
|
||||
public_key.set(it->first);
|
||||
mCache[public_key] = it->second;
|
||||
}
|
||||
|
||||
LL_DEBUGS("ExperienceCache") << "importFile() loaded " << mCache.size() << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLExperienceCache::exportFile(std::ostream& ostr) const
|
||||
{
|
||||
LLSD experiences;
|
||||
|
||||
cache_t::const_iterator it = mCache.begin();
|
||||
for (; it != mCache.end(); ++it)
|
||||
{
|
||||
if (!it->second.has(EXPERIENCE_ID) || it->second[EXPERIENCE_ID].asUUID().isNull() ||
|
||||
it->second.has("DoesNotExist") || (it->second.has(PROPERTIES) && it->second[PROPERTIES].asInteger() & PROPERTY_INVALID))
|
||||
continue;
|
||||
|
||||
experiences[it->first.asString()] = it->second;
|
||||
}
|
||||
|
||||
LLSD data;
|
||||
data["experiences"] = experiences;
|
||||
|
||||
LLSDSerialize::toPrettyXML(data, ostr);
|
||||
}
|
||||
|
||||
// *TODO$: Rider: This method does not seem to be used... it may be useful in testing.
|
||||
void LLExperienceCache::bootstrap(const LLSD& legacyKeys, int initialExpiration)
|
||||
{
|
||||
LLExperienceCacheImpl::mapKeys(legacyKeys);
|
||||
LLSD::array_const_iterator it = legacyKeys.beginArray();
|
||||
for (/**/; it != legacyKeys.endArray(); ++it)
|
||||
{
|
||||
LLSD experience = *it;
|
||||
if (experience.has(EXPERIENCE_ID))
|
||||
{
|
||||
if (!experience.has(EXPIRES))
|
||||
{
|
||||
experience[EXPIRES] = initialExpiration;
|
||||
}
|
||||
processExperience(experience[EXPERIENCE_ID].asUUID(), experience);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("ExperienceCache")
|
||||
<< "Skipping bootstrap entry which is missing " << EXPERIENCE_ID
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLUUID LLExperienceCache::getExperienceId(const LLUUID& private_key, bool null_if_not_found)
|
||||
{
|
||||
if (private_key.isNull())
|
||||
return LLUUID::null;
|
||||
|
||||
LLExperienceCacheImpl::KeyMap::const_iterator it = LLExperienceCacheImpl::privateToPublicKeyMap.find(private_key);
|
||||
if (it == LLExperienceCacheImpl::privateToPublicKeyMap.end())
|
||||
{
|
||||
if (null_if_not_found)
|
||||
{
|
||||
return LLUUID::null;
|
||||
}
|
||||
return private_key;
|
||||
}
|
||||
LL_WARNS("LLExperience") << "converted private key " << private_key << " to experience_id " << it->second << LL_ENDL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
void LLExperienceCache::processExperience(const LLUUID& public_key, const LLSD& experience)
|
||||
{
|
||||
LL_INFOS("ExperienceCache") << "Processing experience \"" << experience[NAME] << "\" with key " << public_key.asString() << LL_ENDL;
|
||||
|
||||
mCache[public_key]=experience;
|
||||
LLSD & row = mCache[public_key];
|
||||
|
||||
if(row.has(EXPIRES))
|
||||
{
|
||||
row[EXPIRES] = row[EXPIRES].asReal() + LLFrameTimer::getTotalSeconds();
|
||||
}
|
||||
|
||||
if(row.has(EXPERIENCE_ID))
|
||||
{
|
||||
mPendingQueue.erase(row[EXPERIENCE_ID].asUUID());
|
||||
}
|
||||
|
||||
//signal
|
||||
signal_map_t::iterator sig_it = mSignalMap.find(public_key);
|
||||
if (sig_it != mSignalMap.end())
|
||||
{
|
||||
signal_ptr signal = sig_it->second;
|
||||
(*signal)(experience);
|
||||
|
||||
mSignalMap.erase(public_key);
|
||||
}
|
||||
}
|
||||
|
||||
const LLExperienceCache::cache_t& LLExperienceCache::getCached()
|
||||
{
|
||||
return mCache;
|
||||
}
|
||||
|
||||
void LLExperienceCache::requestExperiencesCoro(const LLCoroResponder& responder, RequestQueue_t requests)
|
||||
{
|
||||
//LL_INFOS("requestExperiencesCoro") << "url: " << url << LL_ENDL;
|
||||
|
||||
LLSD result = responder.getContent();
|
||||
auto status = responder.getStatus();
|
||||
|
||||
if (!responder.isGoodStatus(status))
|
||||
{
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
|
||||
auto headers = responder.getHeaders();
|
||||
// build dummy entries for the failed requests
|
||||
for (auto request : requests)
|
||||
{
|
||||
LLSD exp = get(request);
|
||||
//leave the properties alone if we already have a cache entry for this xp
|
||||
if (exp.isUndefined())
|
||||
{
|
||||
exp[PROPERTIES] = PROPERTY_INVALID;
|
||||
}
|
||||
exp[EXPIRES] = now + LLExperienceCacheImpl::getErrorRetryDeltaTime(status, headers);
|
||||
exp[EXPERIENCE_ID] = request;
|
||||
exp["key_type"] = EXPERIENCE_ID;
|
||||
exp["uuid"] = request;
|
||||
exp["error"] = status;
|
||||
exp[QUOTA] = DEFAULT_QUOTA;
|
||||
|
||||
processExperience(request, exp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LLSD experiences = result["experience_keys"];
|
||||
|
||||
for (LLSD::array_const_iterator it = experiences.beginArray();
|
||||
it != experiences.endArray(); ++it)
|
||||
{
|
||||
const LLSD& row = *it;
|
||||
LLUUID public_key = row[EXPERIENCE_ID].asUUID();
|
||||
|
||||
LL_DEBUGS("ExperienceCache") << "Received result for " << public_key
|
||||
<< " display '" << row[LLExperienceCache::NAME].asString() << "'" << LL_ENDL;
|
||||
|
||||
processExperience(public_key, row);
|
||||
}
|
||||
|
||||
LLSD error_ids = result["error_ids"];
|
||||
|
||||
for (LLSD::array_const_iterator errIt = error_ids.beginArray();
|
||||
errIt != error_ids.endArray(); ++errIt)
|
||||
{
|
||||
LLUUID id = errIt->asUUID();
|
||||
LLSD exp;
|
||||
exp[EXPIRES] = DEFAULT_EXPIRATION;
|
||||
exp[EXPERIENCE_ID] = id;
|
||||
exp[PROPERTIES] = PROPERTY_INVALID;
|
||||
exp[MISSING] = true;
|
||||
exp[QUOTA] = DEFAULT_QUOTA;
|
||||
|
||||
processExperience(id, exp);
|
||||
LL_WARNS("ExperienceCache") << "LLExperienceResponder::result() error result for " << id << LL_ENDL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLExperienceCache::requestExperiences()
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string urlBase = mCapability("GetExperienceInfo");
|
||||
if (urlBase.empty())
|
||||
{
|
||||
LL_DEBUGS("ExperienceCache") << "No Experience capability." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*urlBase.rbegin() != '/')
|
||||
{
|
||||
urlBase += "/";
|
||||
}
|
||||
urlBase += "id/";
|
||||
|
||||
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
|
||||
const U32 EXP_URL_SEND_THRESHOLD = 3000;
|
||||
constexpr U32 EXP_PAGE_SIZE = EXP_URL_SEND_THRESHOLD / UUID_STR_LENGTH;
|
||||
|
||||
std::ostringstream ostr;
|
||||
ostr << urlBase << "?page_size=" << EXP_PAGE_SIZE;
|
||||
RequestQueue_t requests;
|
||||
|
||||
while (!mRequestQueue.empty())
|
||||
{
|
||||
RequestQueue_t::iterator it = mRequestQueue.begin();
|
||||
LLUUID key = (*it);
|
||||
mRequestQueue.erase(it);
|
||||
requests.insert(key);
|
||||
|
||||
ostr << "&" << EXPERIENCE_ID << "=" << key.asString();
|
||||
mPendingQueue[key] = now;
|
||||
|
||||
if (mRequestQueue.empty() || (ostr.tellp() > EXP_URL_SEND_THRESHOLD))
|
||||
{ // request is placed in the coprocedure pool for the ExpCache cache. Throttling is done by the pool itself.
|
||||
LLHTTPClient::get(ostr.str(), new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::requestExperiencesCoro, this, _1, requests) ));
|
||||
|
||||
ostr.str(std::string());
|
||||
ostr << urlBase << "?page_size=" << EXP_PAGE_SIZE;
|
||||
requests.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool LLExperienceCache::isRequestPending(const LLUUID& public_key)
|
||||
{
|
||||
bool isPending = false;
|
||||
const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
|
||||
|
||||
PendingQueue_t::const_iterator it = mPendingQueue.find(public_key);
|
||||
|
||||
if(it != mPendingQueue.end())
|
||||
{
|
||||
F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
|
||||
isPending = (it->second > expire_time);
|
||||
}
|
||||
|
||||
return isPending;
|
||||
}
|
||||
|
||||
void LLExperienceCache::setCapabilityQuery(LLExperienceCache::CapabilityQuery_t queryfn)
|
||||
{
|
||||
mCapability = queryfn;
|
||||
}
|
||||
|
||||
|
||||
void LLExperienceCache::idleCoro()
|
||||
{
|
||||
const F32 SECS_BETWEEN_REQUESTS = 0.5f;
|
||||
const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
|
||||
|
||||
{
|
||||
static LLFrameTimer sRequestTimer;
|
||||
if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) return;
|
||||
|
||||
if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
|
||||
{
|
||||
eraseExpired();
|
||||
}
|
||||
|
||||
if (!mRequestQueue.empty())
|
||||
{
|
||||
requestExperiences();
|
||||
}
|
||||
}
|
||||
|
||||
// The coroutine system will likely be shut down by the time we get to this point
|
||||
// (or at least no further cycling will occur on it since the user has decided to quit.)
|
||||
}
|
||||
|
||||
void LLExperienceCache::erase(const LLUUID& key)
|
||||
{
|
||||
cache_t::iterator it = mCache.find(key);
|
||||
|
||||
if(it != mCache.end())
|
||||
{
|
||||
mCache.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void LLExperienceCache::eraseExpired()
|
||||
{
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
cache_t::iterator it = mCache.begin();
|
||||
while (it != mCache.end())
|
||||
{
|
||||
cache_t::iterator cur = it;
|
||||
LLSD& exp = cur->second;
|
||||
++it;
|
||||
|
||||
//LL_INFOS("ExperienceCache") << "Testing experience \"" << exp[NAME] << "\" with exp time " << exp[EXPIRES].asReal() << "(now = " << now << ")" << LL_ENDL;
|
||||
|
||||
if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now)
|
||||
{
|
||||
if(!exp.has(EXPERIENCE_ID))
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Removing experience with no id " << LL_ENDL ;
|
||||
mCache.erase(cur);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUUID id = exp[EXPERIENCE_ID].asUUID();
|
||||
LLUUID private_key = exp.has(LLExperienceCache::PRIVATE_KEY) ? exp[LLExperienceCache::PRIVATE_KEY].asUUID():LLUUID::null;
|
||||
if(private_key.notNull() || !exp.has("DoesNotExist"))
|
||||
{
|
||||
fetch(id, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Removing invalid experience " << id << LL_ENDL ;
|
||||
mCache.erase(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLExperienceCache::fetch(const LLUUID& key, bool refresh/* = true*/)
|
||||
{
|
||||
if(!key.isNull() && !isRequestPending(key) && (refresh || mCache.find(key)==mCache.end()))
|
||||
{
|
||||
LL_DEBUGS("ExperienceCache") << " queue request for " << EXPERIENCE_ID << " " << key << LL_ENDL;
|
||||
|
||||
mRequestQueue.insert(key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLExperienceCache::insert(const LLSD& experience_data)
|
||||
{
|
||||
if(experience_data.has(EXPERIENCE_ID))
|
||||
{
|
||||
processExperience(experience_data[EXPERIENCE_ID].asUUID(), experience_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << ": Ignoring cache insert of experience which is missing " << EXPERIENCE_ID << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
const LLSD& LLExperienceCache::get(const LLUUID& key)
|
||||
{
|
||||
static const LLSD empty;
|
||||
|
||||
if(key.isNull())
|
||||
return empty;
|
||||
cache_t::const_iterator it = mCache.find(key);
|
||||
|
||||
if (it != mCache.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
fetch(key);
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
void LLExperienceCache::get(const LLUUID& key, LLExperienceCache::ExperienceGetFn_t slot)
|
||||
{
|
||||
if(key.isNull())
|
||||
return;
|
||||
|
||||
cache_t::const_iterator it = mCache.find(key);
|
||||
if (it != mCache.end())
|
||||
{
|
||||
// ...name already exists in cache, fire callback now
|
||||
callback_signal_t signal;
|
||||
signal.connect(slot);
|
||||
|
||||
signal(it->second);
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(key);
|
||||
|
||||
signal_ptr signal = boost::make_shared<callback_signal_t>();
|
||||
|
||||
std::pair<signal_map_t::iterator, bool> result = mSignalMap.insert(signal_map_t::value_type(key, signal));
|
||||
if (!result.second)
|
||||
signal = (*result.first).second;
|
||||
signal->connect(slot);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (url.empty())
|
||||
{
|
||||
url = mCapability("GetMetadata");
|
||||
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LLSD fields;
|
||||
fields.append("experience");
|
||||
LLSD data;
|
||||
data["object-id"] = objectId;
|
||||
data["item-id"] = itemId;
|
||||
data["fields"] = fields;
|
||||
|
||||
LLHTTPClient::post(url, data, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::fetchAssociatedExperienceCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
auto status = responder.getStatus();
|
||||
|
||||
if (!responder.isGoodStatus(status) || !result.has("experience"))
|
||||
{
|
||||
LLSD failure;
|
||||
if (!status)
|
||||
{
|
||||
failure["error"] = status;
|
||||
failure["message"] = responder.getReason();
|
||||
}
|
||||
else
|
||||
{
|
||||
failure["error"] = -1;
|
||||
failure["message"] = "no experience";
|
||||
}
|
||||
if (fn != nullptr)
|
||||
fn(failure);
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID expId = result["experience"].asUUID();
|
||||
get(expId, fn);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream url;
|
||||
|
||||
url << mCapability("FindExperienceByName") << "?page=" << page << "&page_size=" << SEARCH_PAGE_SIZE << "&query=" << LLURI::escape(text);
|
||||
|
||||
LLHTTPClient::get(url.str(), new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::findExperienceByNameCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::findExperienceByNameCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (!responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
fn(LLSD());
|
||||
return;
|
||||
}
|
||||
|
||||
const LLSD& experiences = result["experience_keys"];
|
||||
for (LLSD::array_const_iterator it = experiences.beginArray(); it != experiences.endArray(); ++it)
|
||||
{
|
||||
insert(*it);
|
||||
}
|
||||
|
||||
fn(result);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// search for experiences owned by the current group
|
||||
std::string url = mCapability("GroupExperiences");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Group Experiences capability" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
url += "?" + groupId.asString();
|
||||
|
||||
LLHTTPClient::get(url, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::getGroupExperiencesCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::getGroupExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (!responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
fn(LLSD());
|
||||
return;
|
||||
}
|
||||
|
||||
const LLSD& experienceIds = result["experience_ids"];
|
||||
fn(experienceIds);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn)
|
||||
{
|
||||
regionExperiences(regioncaps, LLSD(), false, fn);
|
||||
}
|
||||
|
||||
void LLExperienceCache::setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn)
|
||||
{
|
||||
regionExperiences(regioncaps, experiences, true, fn);
|
||||
}
|
||||
|
||||
void LLExperienceCache::regionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, bool update, ExperienceGetFn_t fn)
|
||||
{
|
||||
// search for experiences owned by the current group
|
||||
std::string url = regioncaps("RegionExperiences");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
auto httpRequest = new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::regionExperiencesCoro, this, _1, fn));
|
||||
|
||||
LLSD result;
|
||||
if (update)
|
||||
LLHTTPClient::post(url, experiences, httpRequest);
|
||||
else
|
||||
LLHTTPClient::get(url, httpRequest);
|
||||
}
|
||||
|
||||
void LLExperienceCache::regionExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (!responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
// fn(LLSD());
|
||||
return;
|
||||
}
|
||||
|
||||
fn(result);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString();
|
||||
|
||||
LLHTTPClient::get(url, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("ExperiencePreferences");
|
||||
if (url.empty())
|
||||
return;
|
||||
LLSD permData;
|
||||
LLSD data;
|
||||
permData["permission"] = permission;
|
||||
data[experienceId.asString()] = permData;
|
||||
|
||||
LLHTTPClient::put(url, data, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString();
|
||||
LLHTTPClient::del(url, new LLCoroResponder(
|
||||
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
|
||||
}
|
||||
|
||||
void LLExperienceCache::experiencePermissionCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
|
||||
{
|
||||
// search for experiences owned by the current group
|
||||
|
||||
LLSD result = responder.getContent();
|
||||
|
||||
if (responder.isGoodStatus(responder.getStatus()))
|
||||
{
|
||||
fn(result);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("IsExperienceAdmin");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
url += "?experience_id=" + experienceId.asString();
|
||||
|
||||
LLHTTPClient::get(url, new LLCoroResponder(
|
||||
boost::bind(fn, boost::bind(&LLCoroResponder::getContent, _1))));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void LLExperienceCache::updateExperience(LLSD updateData, ExperienceGetFn_t fn)
|
||||
{
|
||||
if (mCapability == nullptr)
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = mCapability("UpdateExperience");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
updateData.erase(LLExperienceCache::QUOTA);
|
||||
updateData.erase(LLExperienceCache::EXPIRES);
|
||||
updateData.erase(LLExperienceCache::AGENT_ID);
|
||||
|
||||
LLHTTPClient::post(url, updateData, new LLCoroResponder(
|
||||
boost::bind(fn, boost::bind(&LLCoroResponder::getContent, _1))));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
void LLExperienceCacheImpl::mapKeys(const LLSD& legacyKeys)
|
||||
{
|
||||
LLSD::array_const_iterator exp = legacyKeys.beginArray();
|
||||
for (/**/; exp != legacyKeys.endArray(); ++exp)
|
||||
{
|
||||
if (exp->has(LLExperienceCacheImpl::EXPERIENCE_ID) && exp->has(LLExperienceCacheImpl::PRIVATE_KEY))
|
||||
{
|
||||
LLExperienceCacheImpl::privateToPublicKeyMap[(*exp)[LLExperienceCacheImpl::PRIVATE_KEY].asUUID()] =
|
||||
(*exp)[LLExperienceCacheImpl::EXPERIENCE_ID].asUUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return time to retry a request that generated an error, based on
|
||||
// error type and headers. Return value is seconds-since-epoch.
|
||||
F64 LLExperienceCacheImpl::getErrorRetryDeltaTime(S32 status, const AIHTTPReceivedHeaders& headers)
|
||||
{
|
||||
// Retry-After takes priority
|
||||
std::string retry_afters;
|
||||
if (headers.getFirstValue("retry-after", retry_afters))
|
||||
{
|
||||
LLSD retry_after(retry_afters);
|
||||
// We only support the delta-seconds type
|
||||
S32 delta_seconds = retry_after.asInteger();
|
||||
if (delta_seconds > 0)
|
||||
{
|
||||
// ...valid delta-seconds
|
||||
return F64(delta_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
// If no Retry-After, look for Cache-Control max-age
|
||||
// Allow the header to override the default
|
||||
std::string cache_control;
|
||||
if (headers.getFirstValue("cache-control", cache_control))
|
||||
{
|
||||
S32 max_age = 0;
|
||||
if (LLExperienceCacheImpl::maxAgeFromCacheControl(cache_control, &max_age))
|
||||
{
|
||||
LL_WARNS("ExperienceCache")
|
||||
<< "got EXPIRES from headers, max_age " << max_age
|
||||
<< LL_ENDL;
|
||||
return (F64)max_age;
|
||||
}
|
||||
}
|
||||
|
||||
// No information in header, make a guess
|
||||
if (status == 503)
|
||||
{
|
||||
// ...service unavailable, retry soon
|
||||
const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
|
||||
return SERVICE_UNAVAILABLE_DELAY;
|
||||
}
|
||||
else if (status == 499)
|
||||
{
|
||||
// ...we were probably too busy, retry quickly
|
||||
const F64 BUSY_DELAY = 10.0; // 10 seconds
|
||||
return BUSY_DELAY;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...other unexpected error
|
||||
const F64 DEFAULT_DELAY = 3600.0; // 1 hour
|
||||
return DEFAULT_DELAY;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLExperienceCacheImpl::maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age)
|
||||
{
|
||||
// Split the string on "," to get a list of directives
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
tokenizer directives(cache_control, COMMA_SEPARATOR);
|
||||
|
||||
tokenizer::iterator token_it = directives.begin();
|
||||
for ( ; token_it != directives.end(); ++token_it)
|
||||
{
|
||||
// Tokens may have leading or trailing whitespace
|
||||
std::string token = *token_it;
|
||||
LLStringUtil::trim(token);
|
||||
|
||||
if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0)
|
||||
{
|
||||
// ...this token starts with max-age, so let's chop it up by "="
|
||||
tokenizer subtokens(token, EQUALS_SEPARATOR);
|
||||
tokenizer::iterator subtoken_it = subtokens.begin();
|
||||
|
||||
// Must have a token
|
||||
if (subtoken_it == subtokens.end()) return false;
|
||||
std::string subtoken = *subtoken_it;
|
||||
|
||||
// Must exactly equal "max-age"
|
||||
LLStringUtil::trim(subtoken);
|
||||
if (subtoken != MAX_AGE) return false;
|
||||
|
||||
// Must have another token
|
||||
++subtoken_it;
|
||||
if (subtoken_it == subtokens.end()) return false;
|
||||
subtoken = *subtoken_it;
|
||||
|
||||
// Must be a valid integer
|
||||
// *NOTE: atoi() returns 0 for invalid values, so we have to
|
||||
// check the string first.
|
||||
// *TODO: Do servers ever send "0000" for zero? We don't handle it
|
||||
LLStringUtil::trim(subtoken);
|
||||
if (subtoken == "0")
|
||||
{
|
||||
*max_age = 0;
|
||||
return true;
|
||||
}
|
||||
S32 val = atoi( subtoken.c_str() );
|
||||
if (val > 0 && val < S32_MAX)
|
||||
{
|
||||
*max_age = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
181
indra/llmessage/llexperiencecache.h
Normal file
181
indra/llmessage/llexperiencecache.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* @file llexperiencecache.h
|
||||
* @brief Caches information relating to experience keys
|
||||
*
|
||||
* $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_LLEXPERIENCECACHE_H
|
||||
#define LL_LLEXPERIENCECACHE_H
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llsd.h"
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
struct LLCoroResponder;
|
||||
class LLSD;
|
||||
class LLUUID;
|
||||
|
||||
|
||||
class LLExperienceCache final : public LLSingleton < LLExperienceCache >
|
||||
{
|
||||
friend class LLSingleton<LLExperienceCache>;
|
||||
LLExperienceCache();
|
||||
|
||||
public:
|
||||
typedef std::function<std::string(const std::string &)> CapabilityQuery_t;
|
||||
typedef std::function<void(const LLSD &)> ExperienceGetFn_t;
|
||||
|
||||
void idleCoro();
|
||||
void setCapabilityQuery(CapabilityQuery_t queryfn);
|
||||
void cleanup();
|
||||
|
||||
//-------------------------------------------
|
||||
// Cache methods
|
||||
void erase(const LLUUID& key);
|
||||
bool fetch(const LLUUID& key, bool refresh = false);
|
||||
void insert(const LLSD& experience_data);
|
||||
const LLSD& get(const LLUUID& key);
|
||||
void get(const LLUUID& key, ExperienceGetFn_t slot); // If name information is in cache, callback will be called immediately.
|
||||
|
||||
bool isRequestPending(const LLUUID& public_key);
|
||||
|
||||
//-------------------------------------------
|
||||
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, ExperienceGetFn_t fn) { fetchAssociatedExperience(objectId, itemId, LLStringUtil::null, fn); }
|
||||
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn);
|
||||
void findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn);
|
||||
void getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn);
|
||||
|
||||
// the Get/Set Region Experiences take a CapabilityQuery to get the capability since
|
||||
// the region being queried may not be the region that the agent is standing on.
|
||||
void getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn);
|
||||
void setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn);
|
||||
|
||||
void getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn);
|
||||
void setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn);
|
||||
void forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn);
|
||||
|
||||
void getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn);
|
||||
|
||||
void updateExperience(LLSD updateData, ExperienceGetFn_t fn);
|
||||
//-------------------------------------------
|
||||
static const std::string NAME; // "name"
|
||||
static const std::string EXPERIENCE_ID; // "public_id"
|
||||
static const std::string AGENT_ID; // "agent_id"
|
||||
static const std::string GROUP_ID; // "group_id"
|
||||
static const std::string PROPERTIES; // "properties"
|
||||
static const std::string EXPIRES; // "expiration"
|
||||
static const std::string DESCRIPTION; // "description"
|
||||
static const std::string QUOTA; // "quota"
|
||||
static const std::string MATURITY; // "maturity"
|
||||
static const std::string METADATA; // "extended_metadata"
|
||||
static const std::string SLURL; // "slurl"
|
||||
|
||||
static const std::string MISSING; // "DoesNotExist"
|
||||
|
||||
// should be in sync with experience-api/experiences/models.py
|
||||
static const int PROPERTY_INVALID; // 1 << 0
|
||||
static const int PROPERTY_PRIVILEGED; // 1 << 3
|
||||
static const int PROPERTY_GRID; // 1 << 4
|
||||
static const int PROPERTY_PRIVATE; // 1 << 5
|
||||
static const int PROPERTY_DISABLED; // 1 << 6
|
||||
static const int PROPERTY_SUSPENDED; // 1 << 7
|
||||
|
||||
private:
|
||||
virtual ~LLExperienceCache();
|
||||
|
||||
void initSingleton() override;
|
||||
|
||||
// Callback types for get()
|
||||
typedef boost::signals2::signal < void(const LLSD &) > callback_signal_t;
|
||||
typedef boost::shared_ptr<callback_signal_t> signal_ptr;
|
||||
// May have multiple callbacks for a single ID, which are
|
||||
// represented as multiple slots bound to the signal.
|
||||
// Avoid copying signals via pointers.
|
||||
typedef std::map<LLUUID, signal_ptr> signal_map_t;
|
||||
typedef std::map<LLUUID, LLSD> cache_t;
|
||||
|
||||
typedef uuid_set_t RequestQueue_t;
|
||||
typedef std::map<LLUUID, F64> PendingQueue_t;
|
||||
|
||||
//--------------------------------------------
|
||||
static const std::string PRIVATE_KEY; // "private_id"
|
||||
|
||||
// default values
|
||||
static const F64 DEFAULT_EXPIRATION; // 600.0
|
||||
static const S32 DEFAULT_QUOTA; // 128 this is megabytes
|
||||
static const int SEARCH_PAGE_SIZE;
|
||||
|
||||
//--------------------------------------------
|
||||
void processExperience(const LLUUID& public_key, const LLSD& experience);
|
||||
|
||||
//--------------------------------------------
|
||||
cache_t mCache;
|
||||
signal_map_t mSignalMap;
|
||||
RequestQueue_t mRequestQueue;
|
||||
PendingQueue_t mPendingQueue;
|
||||
|
||||
LLFrameTimer mEraseExpiredTimer; // Periodically clean out expired entries from the cache
|
||||
CapabilityQuery_t mCapability;
|
||||
std::string mCacheFileName;
|
||||
bool mShutdown;
|
||||
|
||||
void eraseExpired();
|
||||
void requestExperiencesCoro(const LLCoroResponder& responder, RequestQueue_t);
|
||||
void requestExperiences();
|
||||
|
||||
void fetchAssociatedExperienceCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
|
||||
void findExperienceByNameCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
|
||||
void getGroupExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
|
||||
void regionExperiences(CapabilityQuery_t regioncaps, const LLSD& experiences, bool update, ExperienceGetFn_t fn);
|
||||
void regionExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn);
|
||||
void experiencePermissionCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn);
|
||||
|
||||
void bootstrap(const LLSD& legacyKeys, int initialExpiration);
|
||||
void exportFile(std::ostream& ostr) const;
|
||||
void importFile(std::istream& istr);
|
||||
|
||||
//
|
||||
const cache_t& getCached();
|
||||
|
||||
// maps an experience private key to the experience id
|
||||
LLUUID getExperienceId(const LLUUID& private_key, bool null_if_not_found=false);
|
||||
|
||||
//=====================================================================
|
||||
inline friend std::ostream &operator << (std::ostream &os, const LLExperienceCache &cache)
|
||||
{
|
||||
cache.exportFile(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline friend std::istream &operator >> (std::istream &is, LLExperienceCache &cache)
|
||||
{
|
||||
cache.importFile(is);
|
||||
return is;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // LL_LLEXPERIENCECACHE_H
|
||||
@@ -168,19 +168,20 @@ const U32 ESTATE_ACCESS_ALL = ESTATE_ACCESS_ALLOWED_AGENTS
|
||||
| ESTATE_ACCESS_BANNED_AGENTS
|
||||
| ESTATE_ACCESS_MANAGERS;
|
||||
|
||||
// for EstateOwnerRequest, estateaccessdelta message
|
||||
const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1 << 0;
|
||||
const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1 << 1;
|
||||
// for EstateOwnerRequest, estateaccessdelta, estateexperiencedelta messages
|
||||
const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1U << 0;
|
||||
const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1U << 1;
|
||||
|
||||
const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1 << 2;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1 << 3;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1 << 4;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1 << 5;
|
||||
const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1 << 6;
|
||||
const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1 << 7;
|
||||
const U32 ESTATE_ACCESS_MANAGER_ADD = 1 << 8;
|
||||
const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1 << 9;
|
||||
const U32 ESTATE_ACCESS_NO_REPLY = 1 << 10;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1U << 2;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1U << 3;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1U << 4;
|
||||
const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1U << 5;
|
||||
const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1U << 6;
|
||||
const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1U << 7;
|
||||
const U32 ESTATE_ACCESS_MANAGER_ADD = 1U << 8;
|
||||
const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1U << 9;
|
||||
const U32 ESTATE_ACCESS_NO_REPLY = 1U << 10;
|
||||
const U32 ESTATE_ACCESS_FAILED_BAN_ESTATE_MANAGER = 1U << 11;
|
||||
|
||||
const S32 ESTATE_MAX_MANAGERS = 15;
|
||||
const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access, banned
|
||||
@@ -191,6 +192,26 @@ const U32 SWD_OTHERS_LAND_ONLY = (1 << 0);
|
||||
const U32 SWD_ALWAYS_RETURN_OBJECTS = (1 << 1);
|
||||
const U32 SWD_SCRIPTED_ONLY = (1 << 2);
|
||||
|
||||
// Controls experience key validity in the estate
|
||||
const U32 EXPERIENCE_KEY_TYPE_NONE = 0;
|
||||
const U32 EXPERIENCE_KEY_TYPE_BLOCKED = 1;
|
||||
const U32 EXPERIENCE_KEY_TYPE_ALLOWED = 2;
|
||||
const U32 EXPERIENCE_KEY_TYPE_TRUSTED = 3;
|
||||
|
||||
const U32 EXPERIENCE_KEY_TYPE_FIRST = EXPERIENCE_KEY_TYPE_BLOCKED;
|
||||
const U32 EXPERIENCE_KEY_TYPE_LAST = EXPERIENCE_KEY_TYPE_TRUSTED;
|
||||
|
||||
//
|
||||
const U32 ESTATE_EXPERIENCE_TRUSTED_ADD = 1U << 2;
|
||||
const U32 ESTATE_EXPERIENCE_TRUSTED_REMOVE = 1U << 3;
|
||||
const U32 ESTATE_EXPERIENCE_ALLOWED_ADD = 1U << 4;
|
||||
const U32 ESTATE_EXPERIENCE_ALLOWED_REMOVE = 1U << 5;
|
||||
const U32 ESTATE_EXPERIENCE_BLOCKED_ADD = 1U << 6;
|
||||
const U32 ESTATE_EXPERIENCE_BLOCKED_REMOVE = 1U << 7;
|
||||
|
||||
const S32 ESTATE_MAX_EXPERIENCE_IDS = 8;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1393,6 +1393,8 @@ char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance
|
||||
char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion");
|
||||
char const* const _PREHASH_AppearanceHover = LLMessageStringTable::getInstance()->getString("AppearanceHover");
|
||||
char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->getString("HoverHeight");
|
||||
char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience");
|
||||
char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID");
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
char const* const _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX");
|
||||
|
||||
@@ -1393,6 +1393,8 @@ extern char const* const _PREHASH_AppearanceVersion;
|
||||
extern char const* const _PREHASH_CofVersion;
|
||||
extern char const* const _PREHASH_AppearanceHover;
|
||||
extern char const* const _PREHASH_HoverHeight;
|
||||
extern char const* const _PREHASH_Experience;
|
||||
extern char const* const _PREHASH_ExperienceID;
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
extern char const* const _PREHASH_RegionSizeX;
|
||||
|
||||
@@ -7,6 +7,7 @@ include(LLCommon)
|
||||
include(LLMath)
|
||||
include(LLMessage)
|
||||
include(LLRender)
|
||||
include(Boost)
|
||||
|
||||
include_directories(
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
@@ -46,14 +47,6 @@ set(llplugin_HEADER_FILES
|
||||
set_source_files_properties(${llplugin_HEADER_FILES}
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
if(NOT WORD_SIZE EQUAL 32)
|
||||
if(WINDOWS)
|
||||
# add_definitions(/FIXED:NO)
|
||||
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
|
||||
add_definitions(-fPIC)
|
||||
endif(WINDOWS)
|
||||
endif (NOT WORD_SIZE EQUAL 32)
|
||||
|
||||
list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
|
||||
|
||||
add_library (llplugin ${llplugin_SOURCE_FILES})
|
||||
@@ -67,6 +60,8 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
set_target_properties(llplugin PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
||||
add_subdirectory(slplugin)
|
||||
|
||||
# # Add tests
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
project(SLPlugin)
|
||||
|
||||
include(00-Common)
|
||||
include(Linking)
|
||||
include(LLCommon)
|
||||
include(LLPlugin)
|
||||
include(Linking)
|
||||
@@ -69,12 +68,7 @@ target_link_libraries(SLPlugin
|
||||
${LLCOMMON_LIBRARIES}
|
||||
${APRUTIL_LIBRARIES}
|
||||
${PLUGIN_API_WINDOWS_LIBRARIES}
|
||||
)
|
||||
|
||||
add_dependencies(SLPlugin
|
||||
${LLPLUGIN_LIBRARIES}
|
||||
${LLMESSAGE_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
${PTHREAD_LIBRARY}
|
||||
)
|
||||
|
||||
if (DARWIN)
|
||||
|
||||
@@ -42,8 +42,11 @@ LLMaterialID::LLMaterialID()
|
||||
|
||||
LLMaterialID::LLMaterialID(const LLSD& pMaterialID)
|
||||
{
|
||||
llassert(pMaterialID.isBinary());
|
||||
parseFromBinary(pMaterialID.asBinary());
|
||||
llassert(pMaterialID.isBinary() || pMaterialID.isUUID());
|
||||
if (pMaterialID.isUUID())
|
||||
set(pMaterialID.asUUID().mData);
|
||||
else
|
||||
parseFromBinary(pMaterialID.asBinary());
|
||||
}
|
||||
|
||||
LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID)
|
||||
|
||||
@@ -36,6 +36,7 @@ class LLMaterialID
|
||||
{
|
||||
public:
|
||||
LLMaterialID();
|
||||
LLMaterialID(const LLUUID& id) { set(id.mData); }
|
||||
LLMaterialID(const LLSD& pMaterialID);
|
||||
LLMaterialID(const LLSD::Binary& pMaterialID);
|
||||
LLMaterialID(const void* pMemory);
|
||||
|
||||
@@ -1037,14 +1037,26 @@ S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_fa
|
||||
}
|
||||
|
||||
//assign exception faces to cur_ptr
|
||||
if (exception_faces >= (0x1 << 7))
|
||||
if (exception_faces >= ((U64)0x1 << 7))
|
||||
{
|
||||
if (exception_faces >= (0x1 << 14))
|
||||
if (exception_faces >= ((U64)0x1 << 14))
|
||||
{
|
||||
if (exception_faces >= (0x1 << 21))
|
||||
if (exception_faces >= ((U64)0x1 << 21))
|
||||
{
|
||||
if (exception_faces >= (0x1 << 28))
|
||||
if (exception_faces >= ((U64)0x1 << 28))
|
||||
{
|
||||
if (exception_faces >= ((U64)0x1 << 35))
|
||||
{
|
||||
if (exception_faces >= ((U64)0x1 << 42))
|
||||
{
|
||||
if (exception_faces >= ((U64)0x1 << 49))
|
||||
{
|
||||
*cur_ptr++ = (U8)(((exception_faces >> 49) & 0x7F) | 0x80);
|
||||
}
|
||||
*cur_ptr++ = (U8)(((exception_faces >> 42) & 0x7F) | 0x80);
|
||||
}
|
||||
*cur_ptr++ = (U8)(((exception_faces >> 35) & 0x7F) | 0x80);
|
||||
}
|
||||
*cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80);
|
||||
}
|
||||
*cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80);
|
||||
@@ -1053,6 +1065,7 @@ S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_fa
|
||||
}
|
||||
*cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80);
|
||||
}
|
||||
|
||||
|
||||
*cur_ptr++ = (U8)(exception_faces & 0x7F);
|
||||
|
||||
@@ -1112,7 +1125,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat
|
||||
// Includes information about image ID, color, scale S,T, offset S,T and rotation
|
||||
BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
|
||||
{
|
||||
const U32 MAX_TES = 32;
|
||||
const U32 MAX_TES = 45;
|
||||
|
||||
U8 image_ids[MAX_TES*16];
|
||||
U8 colors[MAX_TES*4];
|
||||
@@ -1197,7 +1210,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
|
||||
|
||||
BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
|
||||
{
|
||||
const U32 MAX_TES = 32;
|
||||
const U32 MAX_TES = 45;
|
||||
|
||||
U8 image_ids[MAX_TES*16];
|
||||
U8 colors[MAX_TES*4];
|
||||
@@ -1401,7 +1414,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
|
||||
{
|
||||
// use a negative block_num to indicate a single-block read (a non-variable block)
|
||||
S32 retval = 0;
|
||||
const U32 MAX_TES = 32;
|
||||
const U32 MAX_TES = 45;
|
||||
|
||||
// Avoid construction of 32 UUIDs per call
|
||||
static LLUUID image_ids[MAX_TES];
|
||||
|
||||
@@ -320,7 +320,7 @@ public:
|
||||
// - Vir
|
||||
struct LLTEContents
|
||||
{
|
||||
static const U32 MAX_TES = 32;
|
||||
static const U32 MAX_TES = 45;
|
||||
|
||||
U8 image_data[MAX_TES*16];
|
||||
U8 colors[MAX_TES*4];
|
||||
|
||||
@@ -306,6 +306,13 @@ public:
|
||||
SPECULAR_MAP,
|
||||
NUM_TEXTURE_CHANNELS,
|
||||
};
|
||||
|
||||
enum eVolumeTexIndex
|
||||
{
|
||||
LIGHT_TEX = 0,
|
||||
SCULPT_TEX,
|
||||
NUM_VOLUME_TEXTURE_CHANNELS,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TRIANGLES = 0,
|
||||
|
||||
@@ -92,7 +92,7 @@ U64 LLVBOPool::sBytesPooled = 0;
|
||||
U64 LLVBOPool::sIndexBytesPooled = 0;
|
||||
std::vector<U32> LLVBOPool::sPendingDeletions;
|
||||
|
||||
std::list<U32> LLVertexBuffer::sAvailableVAOName;
|
||||
std::vector<U32> LLVertexBuffer::sAvailableVAOName;
|
||||
U32 LLVertexBuffer::sCurVAOName = 1;
|
||||
|
||||
U64 LLVertexBuffer::sAllocatedIndexBytes = 0;
|
||||
@@ -480,8 +480,8 @@ U32 LLVertexBuffer::getVAOName()
|
||||
|
||||
if (!sAvailableVAOName.empty())
|
||||
{
|
||||
ret = sAvailableVAOName.front();
|
||||
sAvailableVAOName.pop_front();
|
||||
ret = sAvailableVAOName.back();
|
||||
sAvailableVAOName.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -998,8 +998,8 @@ void LLVertexBuffer::cleanupClass()
|
||||
|
||||
if (!sAvailableVAOName.empty())
|
||||
{
|
||||
glDeleteVertexArrays(1, &sAvailableVAOName.front());
|
||||
sAvailableVAOName.pop_front();
|
||||
glDeleteVertexArrays(sAvailableVAOName.size(), sAvailableVAOName.data());
|
||||
sAvailableVAOName.clear();
|
||||
}
|
||||
sLastMask = 0;
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
static LLVBOPool sStreamIBOPool;
|
||||
static LLVBOPool sDynamicIBOPool;
|
||||
|
||||
static std::list<U32> sAvailableVAOName;
|
||||
static std::vector<U32> sAvailableVAOName;
|
||||
static U32 sCurVAOName;
|
||||
|
||||
static bool sUseStreamDraw;
|
||||
|
||||
@@ -24,6 +24,7 @@ include_directories(
|
||||
)
|
||||
|
||||
set(llui_SOURCE_FILES
|
||||
lfidbearer.cpp
|
||||
llaccordionctrl.cpp
|
||||
llaccordionctrltab.cpp
|
||||
llalertdialog.cpp
|
||||
@@ -36,6 +37,7 @@ set(llui_SOURCE_FILES
|
||||
lldraghandle.cpp
|
||||
lleditmenuhandler.cpp
|
||||
llfiltereditor.cpp
|
||||
llflatlistview.cpp
|
||||
llfloater.cpp
|
||||
llflyoutbutton.cpp
|
||||
llfocusmgr.cpp
|
||||
@@ -101,6 +103,7 @@ set(llui_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
ailist.h
|
||||
lfidbearer.h
|
||||
llaccordionctrl.h
|
||||
llaccordionctrltab.h
|
||||
llalertdialog.h
|
||||
@@ -114,6 +117,7 @@ set(llui_HEADER_FILES
|
||||
lldraghandle.h
|
||||
lleditmenuhandler.h
|
||||
llfiltereditor.h
|
||||
llflatlistview.h
|
||||
llfloater.h
|
||||
llflyoutbutton.h
|
||||
llfocusmgr.h
|
||||
|
||||
59
indra/llui/lfidbearer.cpp
Normal file
59
indra/llui/lfidbearer.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Copyright (C) 2019 Liru Færs
|
||||
*
|
||||
* LFIDBearer is a class that holds an ID or IDs that menus can use
|
||||
*
|
||||
* 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 */
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "lfidbearer.h"
|
||||
#include "llmenugl.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
const std::array<const std::string, LFIDBearer::COUNT> LFIDBearer::sMenuStrings
|
||||
{
|
||||
"menu_avs_list.xml" // 0
|
||||
, "menu_groups_list.xml" // 1
|
||||
, "menu_objects_list.xml" // 2
|
||||
, "menu_experiences.xml" // 3
|
||||
};
|
||||
std::array<LLMenuGL*, LFIDBearer::COUNT> LFIDBearer::sMenus {};
|
||||
|
||||
const LFIDBearer* LFIDBearer::sActive = nullptr;
|
||||
LFIDBearer::Type LFIDBearer::sActiveType = LFIDBearer::AVATAR;
|
||||
uuid_vec_t LFIDBearer::sActiveIDs {};
|
||||
|
||||
void LFIDBearer::buildMenus()
|
||||
{
|
||||
auto& factory = LLUICtrlFactory::instance();
|
||||
for (auto i = 0; i < COUNT; ++i)
|
||||
sMenus[i] = factory.buildMenu(sMenuStrings[i], LLMenuGL::sMenuContainer);
|
||||
}
|
||||
|
||||
LLMenuGL* LFIDBearer::showMenu(LLView* self, const std::string& menu_name, S32 x, S32 y, std::function<void(LLMenuGL*)> on_menu_built)
|
||||
{
|
||||
auto menu = LLUICtrlFactory::instance().buildMenu(menu_name, LLMenuGL::sMenuContainer);
|
||||
if (on_menu_built) on_menu_built(menu);
|
||||
showMenu(self, menu, x, y);
|
||||
return menu;
|
||||
}
|
||||
|
||||
void LFIDBearer::showMenu(LLView* self, LLMenuGL* menu, S32 x, S32 y)
|
||||
{
|
||||
setActive(); // Menu listeners rely on this
|
||||
menu->buildDrawLabels();
|
||||
menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(self, menu, x, y);
|
||||
}
|
||||
73
indra/llui/lfidbearer.h
Normal file
73
indra/llui/lfidbearer.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* Copyright (C) 2019 Liru Færs
|
||||
*
|
||||
* LFIDBearer is a class that holds an ID or IDs that menus can use
|
||||
* This class also bears the type of ID/IDs that it is holding
|
||||
*
|
||||
* 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lluuid.h"
|
||||
|
||||
class LLMenuGL;
|
||||
class LLView;
|
||||
|
||||
struct LFIDBearer
|
||||
{
|
||||
enum Type : S8
|
||||
{
|
||||
MULTIPLE = -2,
|
||||
NONE = -1,
|
||||
AVATAR = 0,
|
||||
GROUP,
|
||||
OBJECT,
|
||||
EXPERIENCE,
|
||||
COUNT
|
||||
};
|
||||
|
||||
virtual ~LFIDBearer() { if (sActive == this) sActive = nullptr; }
|
||||
virtual LLUUID getStringUUIDSelectedItem() const = 0;
|
||||
virtual uuid_vec_t getSelectedIDs() const { return { getStringUUIDSelectedItem() }; }
|
||||
virtual Type getSelectedType() const { return AVATAR; }
|
||||
|
||||
template<typename T> static const T* getActive() { return static_cast<const T*>(sActive); }
|
||||
static const LLUUID& getActiveSelectedID() { return sActiveIDs.empty() ? LLUUID::null : sActiveIDs[0]; }
|
||||
static const uuid_vec_t& getActiveSelectedIDs() { return sActiveIDs; }
|
||||
static size_t getActiveNumSelected() { return sActiveIDs.size(); }
|
||||
static const Type& getActiveType() { return sActiveType; }
|
||||
|
||||
void setActive() const
|
||||
{
|
||||
sActive = this;
|
||||
sActiveType = getSelectedType();
|
||||
sActiveIDs = getSelectedIDs();
|
||||
//sActiveIDs or even some kinda hybrid map, if Type is MULTIPLE fill the vals? and remove a buncha virtual functions?
|
||||
}
|
||||
|
||||
static void buildMenus();
|
||||
LLMenuGL* showMenu(LLView* self, const std::string& menu_name, S32 x, S32 y, std::function<void(LLMenuGL*)> on_menu_built = nullptr);
|
||||
void showMenu(LLView* self, LLMenuGL* menu, S32 x, S32 y);
|
||||
|
||||
protected:
|
||||
// Menus that recur, such as general avatars or groups menus
|
||||
static const std::array<const std::string, COUNT> sMenuStrings;
|
||||
static std::array<LLMenuGL*, COUNT> sMenus;
|
||||
|
||||
private:
|
||||
static const LFIDBearer* sActive;
|
||||
static Type sActiveType;
|
||||
static uuid_vec_t sActiveIDs;
|
||||
};
|
||||
@@ -200,9 +200,14 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
|
||||
// if we haven't already gotten a value from our control_name and
|
||||
// if providing user text entry or descriptive label
|
||||
// don't select an item under the hood
|
||||
if (combo_box->getControlName().empty() && !combo_box->acceptsTextInput() && combo_box->mLabel.empty())
|
||||
if (combo_box->getControlName().empty())
|
||||
{
|
||||
combo_box->selectFirstItem();
|
||||
const auto text = combo_box->acceptsTextInput();
|
||||
std::string label;
|
||||
if (node->getAttributeString("label", label))
|
||||
text ? combo_box->setLabel(label) : (void)combo_box->mList->selectItemByLabel(label, FALSE);
|
||||
else if (!text && combo_box->mLabel.empty())
|
||||
combo_box->selectFirstItem();
|
||||
}
|
||||
|
||||
return combo_box;
|
||||
@@ -441,8 +446,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
|
||||
|
||||
if (!mAllowTextEntry)
|
||||
{
|
||||
mButton->setLabelUnselected(name);
|
||||
mButton->setLabelSelected(name);
|
||||
mButton->setLabel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,9 +464,7 @@ void LLComboBox::updateLabel()
|
||||
// the combo button label.
|
||||
if (!mAllowTextEntry)
|
||||
{
|
||||
std::string label = getSelectedItemLabel();
|
||||
mButton->setLabelUnselected(label);
|
||||
mButton->setLabelSelected(label);
|
||||
mButton->setLabel(getSelectedItemLabel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,13 +510,16 @@ void LLComboBox::onFocusLost()
|
||||
|
||||
void LLComboBox::setButtonVisible(BOOL visible)
|
||||
{
|
||||
static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
|
||||
|
||||
mButton->setVisible(visible);
|
||||
if (mTextEntry)
|
||||
{
|
||||
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
if (visible)
|
||||
{
|
||||
text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton");
|
||||
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
|
||||
text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
|
||||
}
|
||||
//mTextEntry->setRect(text_entry_rect);
|
||||
mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
|
||||
@@ -553,18 +558,21 @@ S32 LLComboBox::getCurrentIndex() const
|
||||
|
||||
void LLComboBox::updateLayout()
|
||||
{
|
||||
static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
|
||||
LLRect rect = getLocalRect();
|
||||
if (mAllowTextEntry)
|
||||
{
|
||||
S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton");
|
||||
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size,
|
||||
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
|
||||
S32 shadow_size = drop_shadow_button;
|
||||
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size,
|
||||
rect.mTop, rect.mRight, rect.mBottom));
|
||||
mButton->setTabStop(FALSE);
|
||||
mButton->setHAlign(LLFontGL::HCENTER);
|
||||
|
||||
if (!mTextEntry)
|
||||
{
|
||||
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * shadow_size;
|
||||
text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
|
||||
// clear label on button
|
||||
std::string cur_label = mButton->getLabelSelected();
|
||||
mTextEntry = new LLLineEditor(std::string("combo_text_entry"),
|
||||
@@ -713,6 +721,7 @@ void LLComboBox::showList()
|
||||
mList->setVisible(TRUE);
|
||||
|
||||
setUseBoundingRect(TRUE);
|
||||
// updateBoundingRect();
|
||||
}
|
||||
|
||||
void LLComboBox::hideList()
|
||||
@@ -739,6 +748,7 @@ void LLComboBox::hideList()
|
||||
{
|
||||
gFocusMgr.setTopCtrl(NULL);
|
||||
}
|
||||
// updateBoundingRect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1024,9 +1034,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor)
|
||||
|
||||
void LLComboBox::updateSelection()
|
||||
{
|
||||
if(mSuppressAutoComplete) {
|
||||
return;
|
||||
}
|
||||
if(mSuppressAutoComplete) return;
|
||||
|
||||
LLWString left_wstring = mTextEntry->getWText().substr(0, mTextEntry->getCursor());
|
||||
// user-entered portion of string, based on assumption that any selected
|
||||
@@ -1237,3 +1245,25 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last )
|
||||
return mList->selectItemRange(first, last);
|
||||
}
|
||||
|
||||
|
||||
/* Singu Note: This isn't very necessary for now, let's not bother.
|
||||
static LLRegisterWidget<LLIconsComboBox> register_icons_combo_box("icons_combo_box");
|
||||
|
||||
LLIconsComboBox::Params::Params()
|
||||
: icon_column("icon_column", ICON_COLUMN),
|
||||
label_column("label_column", LABEL_COLUMN)
|
||||
{}
|
||||
|
||||
LLIconsComboBox::LLIconsComboBox(const LLIconsComboBox::Params& p)
|
||||
: LLComboBox(p),
|
||||
mIconColumnIndex(p.icon_column),
|
||||
mLabelColumnIndex(p.label_column)
|
||||
{}
|
||||
|
||||
const std::string LLIconsComboBox::getSelectedItemLabel(S32 column) const
|
||||
{
|
||||
mButton->setImageOverlay(LLComboBox::getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign());
|
||||
|
||||
return LLComboBox::getSelectedItemLabel(mLabelColumnIndex);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
virtual void cut() {};
|
||||
virtual BOOL canCut() const { return FALSE; }
|
||||
|
||||
virtual void copy() {};
|
||||
virtual void copy() const {};
|
||||
virtual BOOL canCopy() const { return FALSE; }
|
||||
|
||||
virtual void paste() {};
|
||||
|
||||
1464
indra/llui/llflatlistview.cpp
Normal file
1464
indra/llui/llflatlistview.cpp
Normal file
File diff suppressed because it is too large
Load Diff
540
indra/llui/llflatlistview.h
Normal file
540
indra/llui/llflatlistview.h
Normal file
@@ -0,0 +1,540 @@
|
||||
/**
|
||||
* @file llflatlistview.h
|
||||
* @brief LLFlatListView base class and extension to support messages for several cases of an empty list.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLATLISTVIEW_H
|
||||
#define LL_LLFLATLISTVIEW_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "lltextbox.h"
|
||||
|
||||
|
||||
/**
|
||||
* LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
|
||||
* LLSD can be associated with each added item, it can keep data from an item in digested form.
|
||||
* Associated LLSD's can be of any type (singular, a map etc.).
|
||||
* Items (LLPanel's subclasses) can be of different height.
|
||||
* The list is LLPanel created in itself and grows in height while new items are added.
|
||||
*
|
||||
* The control can manage selection of its items when the flag "allow_select" is set. Also ability to select
|
||||
* multiple items (by using CTRL) is enabled through setting the flag "multi_select" - if selection is not allowed that flag
|
||||
* is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items)
|
||||
* since any item of the list was selected.
|
||||
*
|
||||
* Examples of using this control are presented in Picks panel (My Profile and Profile View), where this control is used to
|
||||
* manage the list of pick items.
|
||||
*
|
||||
* ASSUMPTIONS AND STUFF
|
||||
* - NULL pointers and undefined LLSD's are not accepted by any method of this class unless specified otherwise
|
||||
* - Order of returned selected items are not guaranteed
|
||||
* - The control assumes that all items being added are unique.
|
||||
*/
|
||||
class LLFlatListView : public LLScrollContainer, public LLEditMenuHandler
|
||||
{
|
||||
LOG_CLASS(LLFlatListView);
|
||||
public:
|
||||
|
||||
/**
|
||||
* Abstract comparator for comparing flat list items in a form of LLPanel
|
||||
*/
|
||||
class ItemComparator
|
||||
{
|
||||
public:
|
||||
ItemComparator() {};
|
||||
virtual ~ItemComparator() {};
|
||||
|
||||
/** Returns true if item1 < item2, false otherwise */
|
||||
virtual bool compare(const LLPanel* item1, const LLPanel* item2) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents reverse comparator which acts as a decorator for a comparator that need to be reversed
|
||||
*/
|
||||
class ItemReverseComparator : public ItemComparator
|
||||
{
|
||||
public:
|
||||
ItemReverseComparator(const ItemComparator& comparator) : mComparator(comparator) {};
|
||||
virtual ~ItemReverseComparator() {};
|
||||
|
||||
bool compare(const LLPanel* item1, const LLPanel* item2) const override
|
||||
{
|
||||
return mComparator.compare(item2, item1);
|
||||
}
|
||||
|
||||
private:
|
||||
const ItemComparator& mComparator;
|
||||
};
|
||||
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params>
|
||||
{
|
||||
/** turning on/off selection support */
|
||||
Optional<bool> allow_select;
|
||||
|
||||
/** turning on/off multiple selection (works while clicking and holding CTRL)*/
|
||||
Optional<bool> multi_select;
|
||||
|
||||
/** don't allow to deselect all selected items (for mouse events on items only) */
|
||||
Optional<bool> keep_one_selected;
|
||||
|
||||
/** try to keep selection visible after reshape */
|
||||
Optional<bool> keep_selection_visible_on_reshape;
|
||||
|
||||
/** padding between items */
|
||||
Optional<U32> item_pad;
|
||||
|
||||
/** textbox with info message when list is empty*/
|
||||
Optional<LLTextBox::Params> no_items_text;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
// disable traversal when finding widget to hand focus off to
|
||||
/*virtual*/ BOOL canFocusChildren() const override { return FALSE; }
|
||||
|
||||
/**
|
||||
* Connects callback to signal called when Return key is pressed.
|
||||
*/
|
||||
boost::signals2::connection setReturnCallback( const commit_signal_t::slot_type& cb ) { return mOnReturnSignal.connect(cb); }
|
||||
|
||||
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
|
||||
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
|
||||
|
||||
/** Returns full rect of child panel */
|
||||
const LLRect& getItemsRect() const;
|
||||
|
||||
LLRect getRequiredRect() override { return getItemsRect(); }
|
||||
|
||||
/** Returns distance between items */
|
||||
const S32 getItemsPad() const { return mItemPad; }
|
||||
|
||||
/**
|
||||
* Adds and item and LLSD value associated with it to the list at specified position
|
||||
* @return true if the item was added, false otherwise
|
||||
*/
|
||||
virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Insert item_to_add along with associated value to the list right after the after_item.
|
||||
* @return true if the item was successfully added, false otherwise
|
||||
*/
|
||||
virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value = LLUUID::null);
|
||||
|
||||
/**
|
||||
* Remove specified item
|
||||
* @return true if the item was removed, false otherwise
|
||||
*/
|
||||
virtual bool removeItem(LLPanel* item, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Remove an item specified by value
|
||||
* @return true if the item was removed, false otherwise
|
||||
*/
|
||||
virtual bool removeItemByValue(const LLSD& value, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Remove an item specified by uuid
|
||||
* @return true if the item was removed, false otherwise
|
||||
*/
|
||||
virtual bool removeItemByUUID(const LLUUID& uuid, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Get an item by value
|
||||
* @return the item as LLPanel if associated with value, NULL otherwise
|
||||
*/
|
||||
virtual LLPanel* getItemByValue(const LLSD& value) const;
|
||||
|
||||
/**
|
||||
* Check for item by value in list
|
||||
* @return bool whether item exists by value or not
|
||||
*/
|
||||
virtual bool valueExists(const LLSD& value) const;
|
||||
|
||||
template<class T>
|
||||
T* getTypedItemByValue(const LLSD& value) const
|
||||
{
|
||||
return dynamic_cast<T*>(getItemByValue(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Select or deselect specified item based on select
|
||||
* @return true if succeed, false otherwise
|
||||
*/
|
||||
virtual bool selectItem(LLPanel* item, bool select = true);
|
||||
|
||||
/**
|
||||
* Select or deselect an item by associated value based on select
|
||||
* @return true if succeed, false otherwise
|
||||
*/
|
||||
virtual bool selectItemByValue(const LLSD& value, bool select = true);
|
||||
|
||||
/**
|
||||
* Select or deselect an item by associated uuid based on select
|
||||
* @return true if succeed, false otherwise
|
||||
*/
|
||||
virtual bool selectItemByUUID(const LLUUID& uuid, bool select = true);
|
||||
|
||||
/**
|
||||
* Get all panels stored in the list.
|
||||
*/
|
||||
virtual void getItems(std::vector<LLPanel*>& items) const;
|
||||
|
||||
/**
|
||||
* Get all items values.
|
||||
*/
|
||||
virtual void getValues(std::vector<LLSD>& values) const;
|
||||
|
||||
/**
|
||||
* Get LLSD associated with the first selected item
|
||||
*/
|
||||
virtual LLSD getSelectedValue() const;
|
||||
|
||||
/**
|
||||
* Get LLSD's associated with selected items.
|
||||
* @param selected_values std::vector being populated with LLSD associated with selected items
|
||||
*/
|
||||
virtual void getSelectedValues(std::vector<LLSD>& selected_values) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get LLUUID associated with selected item
|
||||
* @return LLUUID if such was associated with selected item
|
||||
*/
|
||||
virtual LLUUID getSelectedUUID() const;
|
||||
|
||||
/**
|
||||
* Get LLUUIDs associated with selected items
|
||||
* @param selected_uuids An std::vector being populated with LLUUIDs associated with selected items
|
||||
*/
|
||||
virtual void getSelectedUUIDs(uuid_vec_t& selected_uuids) const;
|
||||
|
||||
/** Get the top selected item */
|
||||
virtual LLPanel* getSelectedItem() const;
|
||||
|
||||
/**
|
||||
* Get selected items
|
||||
* @param selected_items An std::vector being populated with pointers to selected items
|
||||
*/
|
||||
virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const;
|
||||
|
||||
|
||||
/**
|
||||
* Resets selection of items.
|
||||
*
|
||||
* It calls onCommit callback if setCommitOnSelectionChange(bool b) was called with "true"
|
||||
* argument for current Flat List.
|
||||
* @param no_commit_on_deselection - if true onCommit callback will not be called
|
||||
*/
|
||||
virtual void resetSelection(bool no_commit_on_deselection = false);
|
||||
|
||||
/**
|
||||
* Sets comment text which will be shown in the list is it is empty.
|
||||
*
|
||||
* Textbox to hold passed text is created while this method is called at the first time.
|
||||
*
|
||||
* @param comment_text - string to be shown as a comment.
|
||||
*/
|
||||
void setNoItemsCommentText( const std::string& comment_text);
|
||||
|
||||
/** Turn on/off multiple selection support */
|
||||
void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; }
|
||||
|
||||
/** Turn on/off selection support */
|
||||
void setAllowSelection(bool can_select) { mAllowSelection = can_select; }
|
||||
|
||||
/** Sets flag whether onCommit should be fired if selection was changed */
|
||||
// FIXME: this should really be a separate signal, since "Commit" implies explicit user action, and selection changes can happen more indirectly.
|
||||
void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; }
|
||||
|
||||
/** Get number of selected items in the list */
|
||||
U32 numSelected() const {return mSelectedItemPairs.size(); }
|
||||
|
||||
/** Get number of (visible) items in the list */
|
||||
U32 size(const bool only_visible_items = true) const;
|
||||
|
||||
/** Removes all items from the list */
|
||||
void clear() override;
|
||||
|
||||
/**
|
||||
* Removes all items that can be detached from the list but doesn't destroy
|
||||
* them, caller responsible to manage items after they are detached.
|
||||
* Detachable item should accept "detach" action via notify() method,
|
||||
* where it disconnect all callbacks, does other valuable routines and
|
||||
* return 1.
|
||||
*/
|
||||
void detachItems(std::vector<LLPanel*>& detached_items);
|
||||
|
||||
/**
|
||||
* Set comparator to use for future sorts.
|
||||
*
|
||||
* This class does NOT manage lifetime of the comparator
|
||||
* but assumes that the comparator is always alive.
|
||||
*/
|
||||
void setComparator(const ItemComparator* comp) { mItemComparator = comp; }
|
||||
void sort();
|
||||
|
||||
bool updateValue(const LLSD& old_value, const LLSD& new_value);
|
||||
|
||||
void scrollToShowFirstSelectedItem();
|
||||
|
||||
void selectFirstItem ();
|
||||
void selectLastItem ();
|
||||
|
||||
S32 notify(const LLSD& info) override;
|
||||
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); // <singu> Old-style
|
||||
|
||||
virtual ~LLFlatListView();
|
||||
protected:
|
||||
|
||||
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
|
||||
typedef std::pair<LLPanel*, LLSD> item_pair_t;
|
||||
|
||||
typedef std::list<item_pair_t*> pairs_list_t;
|
||||
typedef pairs_list_t::iterator pairs_iterator_t;
|
||||
typedef pairs_list_t::const_iterator pairs_const_iterator_t;
|
||||
|
||||
/** An adapter for a ItemComparator */
|
||||
struct ComparatorAdaptor
|
||||
{
|
||||
ComparatorAdaptor(const ItemComparator& comparator) : mComparator(comparator) {};
|
||||
|
||||
bool operator()(const item_pair_t* item_pair1, const item_pair_t* item_pair2) const
|
||||
{
|
||||
return mComparator.compare(item_pair1->first, item_pair2->first);
|
||||
}
|
||||
|
||||
const ItemComparator& mComparator;
|
||||
};
|
||||
|
||||
|
||||
friend class LLUICtrlFactory;
|
||||
LLFlatListView(const std::string& name, const LLRect& rect, bool opaque, const LLColor4& color, const S32& item_pad, bool allow_select, bool multi_select, bool keep_one_selected, bool keep_selection_visible_on_reshape, const std::string& no_items_text);
|
||||
|
||||
/** Manage selection on mouse events */
|
||||
void onItemMouseClick(item_pair_t* item_pair, MASK mask);
|
||||
|
||||
void onItemRightMouseClick(item_pair_t* item_pair, MASK mask);
|
||||
|
||||
/**
|
||||
* Updates position of items.
|
||||
* It does not take into account invisible items.
|
||||
*/
|
||||
virtual void rearrangeItems();
|
||||
|
||||
virtual item_pair_t* getItemPair(LLPanel* item) const;
|
||||
|
||||
virtual item_pair_t* getItemPair(const LLSD& value) const;
|
||||
|
||||
virtual bool selectItemPair(item_pair_t* item_pair, bool select);
|
||||
|
||||
virtual bool selectNextItemPair(bool is_up_direction, bool reset_selection);
|
||||
|
||||
BOOL canSelectAll() const override;
|
||||
void selectAll() override;
|
||||
|
||||
virtual bool isSelected(item_pair_t* item_pair) const;
|
||||
|
||||
virtual bool removeItemPair(item_pair_t* item_pair, bool rearrange);
|
||||
|
||||
bool addItemPairs(pairs_list_t panel_list, bool rearrange = true);
|
||||
|
||||
/**
|
||||
* Notify parent about changed size of internal controls with "size_changes" action
|
||||
*
|
||||
* Size includes Items Rect width and either Items Rect height or comment text height.
|
||||
* Comment text height is included if comment text is set and visible.
|
||||
* List border size is also included into notified size.
|
||||
*/
|
||||
void notifyParentItemsRectChanged();
|
||||
|
||||
BOOL handleKeyHere(KEY key, MASK mask) override;
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void onFocusReceived() override;
|
||||
|
||||
void onFocusLost() override;
|
||||
|
||||
void draw() override;
|
||||
|
||||
LLRect getLastSelectedItemRect();
|
||||
|
||||
void ensureSelectedVisible();
|
||||
|
||||
private:
|
||||
|
||||
void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;}
|
||||
|
||||
void setNoItemsCommentVisible(bool visible) const;
|
||||
|
||||
protected:
|
||||
|
||||
/** Comparator to use when sorting the list. */
|
||||
const ItemComparator* mItemComparator;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
LLPanel* mItemsPanel;
|
||||
|
||||
S32 mItemsNoScrollWidth;
|
||||
|
||||
S32 mBorderThickness;
|
||||
|
||||
/** Items padding */
|
||||
S32 mItemPad;
|
||||
|
||||
/** Selection support flag */
|
||||
bool mAllowSelection;
|
||||
|
||||
/** Multiselection support flag, ignored if selection is not supported */
|
||||
bool mMultipleSelection;
|
||||
|
||||
/**
|
||||
* Flag specified whether onCommit be called if selection is changed in the list.
|
||||
*
|
||||
* Can be ignored in the resetSelection() method.
|
||||
* @see resetSelection()
|
||||
*/
|
||||
bool mCommitOnSelectionChange;
|
||||
|
||||
bool mKeepOneItemSelected;
|
||||
|
||||
bool mIsConsecutiveSelection;
|
||||
|
||||
bool mKeepSelectionVisibleOnReshape;
|
||||
|
||||
/** All pairs of the list */
|
||||
pairs_list_t mItemPairs;
|
||||
|
||||
/** Selected pairs for faster access */
|
||||
pairs_list_t mSelectedItemPairs;
|
||||
|
||||
/**
|
||||
* Rectangle contained previous size of items parent notified last time.
|
||||
* Is used to reduce amount of parentNotify() calls if size was not changed.
|
||||
*/
|
||||
LLRect mPrevNotifyParentRect;
|
||||
|
||||
LLTextBox* mNoItemsCommentTextbox;
|
||||
|
||||
LLViewBorder* mSelectedItemsBorder;
|
||||
|
||||
commit_signal_t mOnReturnSignal;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends LLFlatListView functionality to show different messages when there are no items in the
|
||||
* list depend on whether they are filtered or not.
|
||||
*
|
||||
* Class provides one message per case of empty list.
|
||||
* It also provides protected updateNoItemsMessage() method to be called each time when derived list
|
||||
* is changed to update base mNoItemsCommentTextbox value.
|
||||
*
|
||||
* It is implemented to avoid duplication of this functionality in concrete implementations of the
|
||||
* lists. It is intended to be used as a base class for lists which should support two different
|
||||
* messages for empty state. Can be improved to support more than two messages via state-to-message map.
|
||||
*/
|
||||
class LLFlatListViewEx : public LLFlatListView
|
||||
{
|
||||
public:
|
||||
LOG_CLASS(LLFlatListViewEx);
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
|
||||
{
|
||||
/**
|
||||
* Contains a message for empty list when it does not contain any items at all.
|
||||
*/
|
||||
Optional<std::string> no_items_msg;
|
||||
|
||||
/**
|
||||
* Contains a message for empty list when its items are removed by filtering.
|
||||
*/
|
||||
Optional<std::string> no_filtered_items_msg;
|
||||
Params();
|
||||
};
|
||||
|
||||
// *WORKAROUND: two methods to overload appropriate Params due to localization issue:
|
||||
// no_items_msg & no_filtered_items_msg attributes are not defined as translatable in VLT. See EXT-5931
|
||||
void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; }
|
||||
void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; }
|
||||
|
||||
bool getForceShowingUnmatchedItems();
|
||||
|
||||
void setForceShowingUnmatchedItems(bool show);
|
||||
|
||||
/**
|
||||
* Sets up new filter string and filters the list.
|
||||
*/
|
||||
void setFilterSubString(const std::string& filter_str);
|
||||
std::string getFilterSubString() const { return mFilterSubString; }
|
||||
|
||||
/**
|
||||
* Filters the list, rearranges and notifies parent about shape changes.
|
||||
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
|
||||
*/
|
||||
void filterItems();
|
||||
|
||||
/**
|
||||
* Returns true if last call of filterItems() found at least one matching item
|
||||
*/
|
||||
bool hasMatchedItems();
|
||||
|
||||
protected:
|
||||
LLFlatListViewEx(const Params& p);
|
||||
|
||||
/**
|
||||
* Applies a message for empty list depend on passed argument.
|
||||
*
|
||||
* @param filter_string - if is not empty, message for filtered items will be set, otherwise for
|
||||
* completely empty list. Value of filter string will be passed as search_term in SLURL.
|
||||
*/
|
||||
void updateNoItemsMessage(const std::string& filter_string);
|
||||
|
||||
/**
|
||||
* Applies visibility acording to action and LLFlatListView settings.
|
||||
*
|
||||
* @param item - item we are changing
|
||||
* @param item - action - parameters to determin visibility from
|
||||
*/
|
||||
void updateItemVisibility(LLPanel* item, const LLSD &action);
|
||||
|
||||
private:
|
||||
std::string mNoFilteredItemsMsg;
|
||||
std::string mNoItemsMsg;
|
||||
std::string mFilterSubString;
|
||||
/**
|
||||
* Show list items that don't match current filter
|
||||
*/
|
||||
bool mForceShowingUnmatchedItems;
|
||||
/**
|
||||
* True if last call of filterItems() found at least one matching item
|
||||
*/
|
||||
bool mHasMatchedItems;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -43,18 +43,18 @@
|
||||
#include "lltimer.h"
|
||||
|
||||
#include "llcalc.h"
|
||||
//#include "llclipboard.h"
|
||||
#include "llclipboard.h"
|
||||
#include "llcontrol.h"
|
||||
#include "llbutton.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "llmenugl.h"
|
||||
#include "llrect.h"
|
||||
#include "llresmgr.h"
|
||||
#include "llstring.h"
|
||||
#include "llwindow.h"
|
||||
#include "llui.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llclipboard.h"
|
||||
#include "../newview/lgghunspell_wrapper.h"
|
||||
|
||||
//
|
||||
@@ -178,19 +178,9 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
|
||||
sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga");
|
||||
}
|
||||
mImage = sImage;
|
||||
|
||||
// make the popup menu available
|
||||
//LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view);
|
||||
LLMenuGL* menu = new LLMenuGL("wot");
|
||||
/*if (!menu)
|
||||
{
|
||||
menu = new LLMenuGL(LLStringUtil::null);
|
||||
}*/
|
||||
menu->addChild(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
|
||||
menu->addChild(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
|
||||
menu->addChild(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
|
||||
menu->addChild(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
|
||||
menu->addChild(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
|
||||
menu->addSeparator();
|
||||
LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", LLMenuGL::sMenuContainer);
|
||||
//menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor"));
|
||||
menu->setCanTearOff(FALSE);
|
||||
menu->setVisible(FALSE);
|
||||
@@ -452,40 +442,9 @@ void LLLineEditor::deselect()
|
||||
}
|
||||
|
||||
|
||||
void LLLineEditor::context_cut(void* data)
|
||||
void LLLineEditor::spell_show(void* show)
|
||||
{
|
||||
LLLineEditor* line = (LLLineEditor*)data;
|
||||
if(line)line->cut();
|
||||
}
|
||||
void LLLineEditor::context_copy(void* data)
|
||||
{
|
||||
LLLineEditor* line = (LLLineEditor*)data;
|
||||
if(line)line->copy();
|
||||
}
|
||||
|
||||
|
||||
void LLLineEditor::spell_correct(void* data)
|
||||
{
|
||||
SpellMenuBind* tempBind = (SpellMenuBind*)data;
|
||||
LLLineEditor* line = tempBind->origin;
|
||||
if(tempBind && line)
|
||||
{
|
||||
LL_INFOS() << ((LLMenuItemCallGL *)(tempBind->menuItem))->getName() << " : " << tempBind->origin->getName() << " : " << tempBind->word << LL_ENDL;
|
||||
if(line)line->spellReplace(tempBind);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLLineEditor::spell_show(void * data)
|
||||
{
|
||||
SpellMenuBind* tempBind = (SpellMenuBind*)data;
|
||||
LLLineEditor* line = tempBind->origin;
|
||||
|
||||
if (tempBind && line)
|
||||
{
|
||||
BOOL show = (tempBind->word == "Show Misspellings");
|
||||
glggHunSpell->setSpellCheckHighlight(show);
|
||||
}
|
||||
glggHunSpell->setSpellCheckHighlight(!!show);
|
||||
}
|
||||
|
||||
std::vector<S32> LLLineEditor::getMisspelledWordsPositions()
|
||||
@@ -537,33 +496,15 @@ std::vector<S32> LLLineEditor::getMisspelledWordsPositions()
|
||||
|
||||
void LLLineEditor::spell_add(void* data)
|
||||
{
|
||||
SpellMenuBind* tempBind = (SpellMenuBind*)data;
|
||||
if(tempBind)
|
||||
auto self = static_cast<LLLineEditor*>(data);
|
||||
S32 wordStart = 0, wordLen = 0;
|
||||
if (self->getWordBoundriesAt(self->calculateCursorFromMouse(self->mLastContextMenuX), &wordStart, &wordLen))
|
||||
{
|
||||
glggHunSpell->addWordToCustomDictionary(tempBind->word);
|
||||
tempBind->origin->mPrevSpelledText="";//make it update
|
||||
glggHunSpell->addWordToCustomDictionary(wstring_to_utf8str(self->getWText().substr(wordStart, wordLen)));
|
||||
self->mPrevSpelledText.clear(); //make it update
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLLineEditor::context_paste(void* data)
|
||||
{
|
||||
LLLineEditor* line = (LLLineEditor*)data;
|
||||
if(line)line->paste();
|
||||
}
|
||||
|
||||
void LLLineEditor::context_delete(void* data)
|
||||
{
|
||||
LLLineEditor* line = (LLLineEditor*)data;
|
||||
if(line)line->doDelete();
|
||||
}
|
||||
|
||||
void LLLineEditor::context_selectall(void* data)
|
||||
{
|
||||
LLLineEditor* line = (LLLineEditor*)data;
|
||||
if(line)line->selectAll();
|
||||
}
|
||||
|
||||
void LLLineEditor::startSelection()
|
||||
{
|
||||
mIsSelecting = TRUE;
|
||||
@@ -1178,7 +1119,7 @@ BOOL LLLineEditor::canCopy() const
|
||||
|
||||
|
||||
// copy selection to clipboard
|
||||
void LLLineEditor::copy()
|
||||
void LLLineEditor::copy() const
|
||||
{
|
||||
if( canCopy() )
|
||||
{
|
||||
@@ -1189,12 +1130,19 @@ void LLLineEditor::copy()
|
||||
}
|
||||
|
||||
|
||||
void LLLineEditor::spellReplace(SpellMenuBind* spellData)
|
||||
void LLLineEditor::spell_correct(void* data)
|
||||
{
|
||||
mText.erase(spellData->wordPositionStart,
|
||||
spellData->wordPositionEnd - spellData->wordPositionStart);
|
||||
insert(spellData->word,spellData->wordPositionStart);
|
||||
mCursorPos+=spellData->word.length() - (spellData->wordPositionEnd-spellData->wordPositionStart);
|
||||
auto self = static_cast<LLLineEditor*>(data);
|
||||
S32 wordStart = 0, wordLen = 0;
|
||||
if (self->getWordBoundriesAt(self->calculateCursorFromMouse(self->mLastContextMenuX), &wordStart, &wordLen))
|
||||
{
|
||||
auto word = utf8str_to_wstring(LLMenuGL::sMenuContainer->getActivatedItem()->getLabel());
|
||||
LLWStringUtil::replaceTabsWithSpaces(word, 4);
|
||||
|
||||
self->mText.erase(wordStart, wordLen);
|
||||
self->mText.insert(wordStart, word);
|
||||
self->mCursorPos += word.length() - wordLen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3057,102 +3005,47 @@ void LLLineEditor::showContextMenu(S32 x, S32 y)
|
||||
{
|
||||
gEditMenuHandler = this;
|
||||
|
||||
/*S32 screen_x, screen_y;
|
||||
localPointToScreen(x, y, &screen_x, &screen_y);
|
||||
menu->show(screen_x, screen_y);*/
|
||||
|
||||
|
||||
//setCursorAtLocalPos( x);
|
||||
S32 wordStart = 0;
|
||||
S32 wordLen = 0;
|
||||
S32 pos = calculateCursorFromMouse(x);
|
||||
|
||||
LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
|
||||
if (menu)
|
||||
if(menu->isOpen())
|
||||
{
|
||||
if(menu->isOpen())
|
||||
{
|
||||
menu->setVisible(FALSE);
|
||||
}
|
||||
for (int i = 0;i<(int)suggestionMenuItems.size();i++)
|
||||
{
|
||||
SpellMenuBind * tempBind = suggestionMenuItems[i];
|
||||
if(tempBind)
|
||||
{
|
||||
menu->removeChild((LLMenuItemCallGL *)tempBind->menuItem);
|
||||
((LLMenuItemCallGL *)tempBind->menuItem)->die();
|
||||
//delete tempBind->menuItem;
|
||||
//tempBind->menuItem = NULL;
|
||||
delete tempBind;
|
||||
}
|
||||
}
|
||||
suggestionMenuItems.clear();
|
||||
|
||||
// spell_check="true" in xui
|
||||
menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable);
|
||||
if (!mReadOnly && mSpellCheckable)
|
||||
{
|
||||
// search for word matches
|
||||
bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen);
|
||||
if (is_word_part)
|
||||
{
|
||||
const LLWString& text = mText.getWString();
|
||||
std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen));
|
||||
|
||||
if (!glggHunSpell->isSpelledRight(selectedWord))
|
||||
{
|
||||
//misspelled word here, and you have just right clicked on it!
|
||||
std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
|
||||
|
||||
for (int i = 0; i<(int)suggs.size() ;i++)
|
||||
{
|
||||
SpellMenuBind * tempStruct = new SpellMenuBind;
|
||||
tempStruct->origin = this;
|
||||
tempStruct->word = suggs[i];
|
||||
tempStruct->wordPositionEnd = wordStart + wordLen;
|
||||
tempStruct->wordPositionStart=wordStart;
|
||||
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
|
||||
tempStruct->word, spell_correct, NULL, tempStruct);
|
||||
//new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
|
||||
tempStruct->menuItem = suggMenuItem;
|
||||
suggestionMenuItems.push_back(tempStruct);
|
||||
menu->addChild(suggMenuItem);
|
||||
}
|
||||
SpellMenuBind * tempStruct = new SpellMenuBind;
|
||||
tempStruct->origin = this;
|
||||
tempStruct->word = selectedWord;
|
||||
tempStruct->wordPositionEnd = wordStart + wordLen;
|
||||
tempStruct->wordPositionStart=wordStart;
|
||||
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
|
||||
"Add Word", spell_add, NULL, tempStruct);
|
||||
tempStruct->menuItem = suggMenuItem;
|
||||
suggestionMenuItems.push_back(tempStruct);
|
||||
menu->addChild(suggMenuItem);
|
||||
}
|
||||
}
|
||||
|
||||
SpellMenuBind * tempStruct = new SpellMenuBind;
|
||||
tempStruct->origin = this;
|
||||
if (glggHunSpell->getSpellCheckHighlight())
|
||||
{
|
||||
tempStruct->word = "Hide Misspellings";
|
||||
}
|
||||
else
|
||||
{
|
||||
tempStruct->word = "Show Misspellings";
|
||||
}
|
||||
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
|
||||
tempStruct->word, spell_show, NULL, tempStruct);
|
||||
tempStruct->menuItem = suggMenuItem;
|
||||
suggestionMenuItems.push_back(tempStruct);
|
||||
menu->addChild(suggMenuItem);
|
||||
}
|
||||
|
||||
mLastContextMenuX = x;
|
||||
menu->buildDrawLabels();
|
||||
menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, menu, x, y);
|
||||
menu->setVisible(FALSE);
|
||||
}
|
||||
|
||||
// spell_check="true" in xui
|
||||
if (!mReadOnly && mSpellCheckable)
|
||||
{
|
||||
constexpr auto spell_sep = "Spell Check Sep";
|
||||
// Remove everything after the separator if we added it, because menus don't autodie yet.
|
||||
menu->erase(menu->find(menu->findChild<LLMenuItemGL>(spell_sep)), menu->end());
|
||||
menu->addSeparator(spell_sep);
|
||||
|
||||
// search for word matches
|
||||
S32 wordStart = 0;
|
||||
S32 wordLen = 0;
|
||||
S32 pos = calculateCursorFromMouse(x);
|
||||
if (getWordBoundriesAt(pos, &wordStart, &wordLen))
|
||||
{
|
||||
const auto selectedWord = wstring_to_utf8str(getWText().substr(wordStart, wordLen));
|
||||
|
||||
if (!glggHunSpell->isSpelledRight(selectedWord))
|
||||
{
|
||||
//misspelled word here, and you have just right clicked on it!
|
||||
|
||||
for (const auto& word : glggHunSpell->getSuggestionList(selectedWord))
|
||||
{
|
||||
menu->addChild(new LLMenuItemCallGL(word, spell_correct, nullptr, this));
|
||||
}
|
||||
menu->addChild(new LLMenuItemCallGL("Add Word", spell_add, nullptr, this));
|
||||
}
|
||||
}
|
||||
|
||||
bool show = !glggHunSpell->getSpellCheckHighlight();
|
||||
menu->addChild(new LLMenuItemCallGL(show ? "Show Misspellings" : "Hide Misspellings", spell_show, nullptr, show ? menu : nullptr));
|
||||
}
|
||||
|
||||
mLastContextMenuX = x;
|
||||
menu->buildDrawLabels();
|
||||
menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, menu, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,23 +101,13 @@ public:
|
||||
/*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
|
||||
/*virtual*/ void onMouseCaptureLost();
|
||||
|
||||
struct SpellMenuBind
|
||||
{
|
||||
LLLineEditor* origin;
|
||||
void * menuItem;
|
||||
std::string word;
|
||||
S32 wordPositionStart;
|
||||
S32 wordPositionEnd;
|
||||
};
|
||||
|
||||
virtual void spellReplace(SpellMenuBind* spellData);
|
||||
virtual void insert(std::string what,S32 wher);
|
||||
|
||||
// LLEditMenuHandler overrides
|
||||
virtual void cut();
|
||||
virtual BOOL canCut() const;
|
||||
|
||||
virtual void copy();
|
||||
void copy() const override final;
|
||||
virtual BOOL canCopy() const;
|
||||
|
||||
virtual void paste();
|
||||
@@ -137,11 +127,6 @@ public:
|
||||
virtual void deselect();
|
||||
virtual BOOL canDeselect() const;
|
||||
|
||||
static void context_cut(void* data);
|
||||
static void context_copy(void* data);
|
||||
static void context_paste(void* data);
|
||||
static void context_delete(void* data);
|
||||
static void context_selectall(void* data);
|
||||
static void spell_correct(void* data);
|
||||
static void spell_show(void* data);
|
||||
static void spell_add(void* data);
|
||||
@@ -309,7 +294,6 @@ protected:
|
||||
S32 mEndSpellHere; // the location of the last char on the screen
|
||||
BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field
|
||||
LLFrameTimer mSpellTimer;
|
||||
std::vector<SpellMenuBind* > suggestionMenuItems;
|
||||
S32 mLastContextMenuX;
|
||||
|
||||
// line history support:
|
||||
|
||||
@@ -73,7 +73,6 @@ using namespace LLOldEvents;
|
||||
LLMenuHolderGL *LLMenuGL::sMenuContainer = nullptr;
|
||||
|
||||
S32 MENU_BAR_HEIGHT = 0;
|
||||
S32 MENU_BAR_WIDTH = 0;
|
||||
|
||||
///============================================================================
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
@@ -693,16 +692,17 @@ BOOL LLMenuItemSeparatorGL::handleHover(S32 x, S32 y, MASK mask)
|
||||
// This class represents a vertical separator.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLMenuItemVerticalSeparatorGL
|
||||
class LLMenuItemVerticalSeparatorGL final
|
||||
: public LLMenuItemSeparatorGL
|
||||
{
|
||||
public:
|
||||
LLMenuItemVerticalSeparatorGL( void );
|
||||
LLMenuItemVerticalSeparatorGL(const std::string& name = LLStringUtil::null);
|
||||
|
||||
BOOL handleMouseDown(S32 x, S32 y, MASK mask) override { return FALSE; }
|
||||
};
|
||||
|
||||
LLMenuItemVerticalSeparatorGL::LLMenuItemVerticalSeparatorGL( void )
|
||||
LLMenuItemVerticalSeparatorGL::LLMenuItemVerticalSeparatorGL(const std::string& name)
|
||||
: LLMenuItemSeparatorGL(name)
|
||||
{
|
||||
setLabel( VERTICAL_SEPARATOR_LABEL );
|
||||
}
|
||||
@@ -827,15 +827,15 @@ U32 LLMenuItemTearOffGL::getNominalHeight( void ) const
|
||||
// This class represents a blank, non-functioning item.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLMenuItemBlankGL : public LLMenuItemGL
|
||||
class LLMenuItemBlankGL final : public LLMenuItemGL
|
||||
{
|
||||
public:
|
||||
LLMenuItemBlankGL( void ) : LLMenuItemGL( LLStringUtil::null, LLStringUtil::null )
|
||||
LLMenuItemBlankGL(const std::string& name = LLStringUtil::null) : LLMenuItemGL(name, LLStringUtil::null)
|
||||
{
|
||||
setEnabled(FALSE);
|
||||
}
|
||||
virtual void onCommit( void ) {}
|
||||
virtual void draw( void ) {}
|
||||
void onCommit() override {}
|
||||
void draw() override {}
|
||||
};
|
||||
|
||||
|
||||
@@ -2109,13 +2109,13 @@ LLXMLNodePtr LLMenuGL::getXML(bool save_children) const
|
||||
return node;
|
||||
}
|
||||
|
||||
void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory)
|
||||
void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent)
|
||||
{
|
||||
std::string name(child->getName()->mString);
|
||||
if (child->hasName(LL_MENU_GL_TAG))
|
||||
{
|
||||
// SUBMENU
|
||||
LLMenuGL *submenu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory);
|
||||
LLMenuGL *submenu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, LLUICtrlFactory::getInstance());
|
||||
appendMenu(submenu);
|
||||
if (LLMenuGL::sMenuContainer != NULL)
|
||||
{
|
||||
@@ -2193,7 +2193,7 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory
|
||||
{
|
||||
mask |= MASK_SHIFT;
|
||||
}
|
||||
S32 pipe_pos = shortcut.rfind("|");
|
||||
S32 pipe_pos = shortcut.rfind('|');
|
||||
std::string key_str = shortcut.substr(pipe_pos+1);
|
||||
|
||||
KEY key = KEY_NONE;
|
||||
@@ -2471,63 +2471,80 @@ BOOL LLMenuGL::isOpen()
|
||||
}
|
||||
}
|
||||
// static
|
||||
LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory* factory)
|
||||
{
|
||||
std::string name("menu");
|
||||
node->getAttributeString("name", name);
|
||||
|
||||
std::string label = name;
|
||||
node->getAttributeString("label", label);
|
||||
LLMenuGL* menu = new LLMenuGL(name);
|
||||
|
||||
LLStringUtil::format(label, LLTrans::getDefaultArgs());
|
||||
|
||||
// parse jump key out of label
|
||||
std::string new_menu_label;
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep("_");
|
||||
tokenizer tokens(label, sep);
|
||||
tokenizer::iterator token_iter;
|
||||
|
||||
KEY jump_key = KEY_NONE;
|
||||
S32 token_count = 0;
|
||||
for( token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
|
||||
// Menus can be extended using filename
|
||||
if (node->hasAttribute("filename"))
|
||||
{
|
||||
new_menu_label += (*token_iter);
|
||||
if (token_count > 0)
|
||||
std::string filename;
|
||||
node->getAttributeString("filename", filename);
|
||||
LLXMLNodePtr root;
|
||||
LLUICtrlFactory::getLayeredXMLNode(filename, root);
|
||||
menu->initMenuXML(root, parent);
|
||||
}
|
||||
menu->initMenuXML(node, parent);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
void LLMenuGL::initMenuXML(LLXMLNodePtr node, LLView* parent)
|
||||
{
|
||||
std::string label;
|
||||
if (node->getAttributeString("label", label))
|
||||
{
|
||||
LLStringUtil::format(label, LLTrans::getDefaultArgs());
|
||||
|
||||
// parse jump key out of label
|
||||
std::string new_menu_label;
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
|
||||
boost::char_separator<char> sep("_");
|
||||
|
||||
KEY jump_key = KEY_NONE;
|
||||
S32 token_count = 0;
|
||||
for (auto token : tokenizer(label, sep))
|
||||
{
|
||||
jump_key = (*token_iter).c_str()[0];
|
||||
new_menu_label += token;
|
||||
if (token_count > 0)
|
||||
{
|
||||
jump_key = token.front();
|
||||
}
|
||||
++token_count;
|
||||
}
|
||||
++token_count;
|
||||
|
||||
setLabel(new_menu_label);
|
||||
setJumpKey(jump_key);
|
||||
}
|
||||
|
||||
BOOL opaque = TRUE;
|
||||
node->getAttributeBOOL("opaque", opaque);
|
||||
|
||||
LLMenuGL *menu = new LLMenuGL(name, new_menu_label);
|
||||
|
||||
bool b(false);
|
||||
node->getAttribute_bool("scrollable", b);
|
||||
menu->setScrollable(b);
|
||||
setScrollable(b);
|
||||
|
||||
menu->setJumpKey(jump_key);
|
||||
|
||||
BOOL tear_off = FALSE;
|
||||
node->getAttributeBOOL("tear_off", tear_off);
|
||||
menu->setCanTearOff(tear_off);
|
||||
setCanTearOff(tear_off);
|
||||
|
||||
if (node->hasAttribute("drop_shadow"))
|
||||
{
|
||||
BOOL drop_shadow = FALSE;
|
||||
node->getAttributeBOOL("drop_shadow", drop_shadow);
|
||||
menu->setDropShadowed(drop_shadow);
|
||||
setDropShadowed(drop_shadow);
|
||||
}
|
||||
|
||||
menu->setBackgroundVisible(opaque);
|
||||
setBackgroundVisible(opaque);
|
||||
LLColor4 color(0,0,0,1);
|
||||
if (opaque && LLUICtrlFactory::getAttributeColor(node,"color", color))
|
||||
{
|
||||
menu->setBackgroundColor(color);
|
||||
setBackgroundColor(color);
|
||||
}
|
||||
|
||||
BOOL create_jump_keys = FALSE;
|
||||
@@ -2536,14 +2553,13 @@ LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa
|
||||
LLXMLNodePtr child;
|
||||
for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
|
||||
{
|
||||
menu->parseChildXML(child, parent, factory);
|
||||
parseChildXML(child, parent);
|
||||
}
|
||||
|
||||
if (create_jump_keys)
|
||||
{
|
||||
menu->createJumpKeys();
|
||||
createJumpKeys();
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
@@ -3151,12 +3167,7 @@ void LLMenuGL::erase( S32 begin, S32 end, bool arrange/* = true*/)
|
||||
item_list_t::iterator end_position = mItems.begin();
|
||||
std::advance(end_position, end);
|
||||
|
||||
for (item_list_t::iterator position_iter = start_position; position_iter != end_position; position_iter++)
|
||||
{
|
||||
LLUICtrl::removeChild(*position_iter);
|
||||
}
|
||||
|
||||
mItems.erase(start_position, end_position);
|
||||
erase(start_position, end_position);
|
||||
|
||||
if (arrange)
|
||||
{
|
||||
@@ -3178,7 +3189,7 @@ void LLMenuGL::insert(S32 position, LLView* ctrl, bool arrange /*= true*/)
|
||||
std::advance(position_iter, position);
|
||||
insert(position_iter, item, arrange);
|
||||
}
|
||||
void LLMenuGL::insert(item_list_t::iterator position_iter, LLMenuItemGL* item, bool arrange /*= true*/)
|
||||
void LLMenuGL::insert(item_list_t::const_iterator position_iter, LLMenuItemGL* item, bool arrange /*= true*/)
|
||||
{
|
||||
mItems.insert(position_iter, item);
|
||||
LLUICtrl::addChild(item);
|
||||
@@ -3228,9 +3239,9 @@ BOOL LLMenuGL::append( LLMenuItemGL* item )
|
||||
}
|
||||
|
||||
// add a separator to this menu
|
||||
BOOL LLMenuGL::addSeparator()
|
||||
BOOL LLMenuGL::addSeparator(const std::string& name)
|
||||
{
|
||||
LLMenuItemGL* separator = new LLMenuItemSeparatorGL();
|
||||
LLMenuItemGL* separator = new LLMenuItemSeparatorGL(name);
|
||||
return addChild(separator);
|
||||
}
|
||||
|
||||
@@ -3317,11 +3328,6 @@ void LLMenuGL::setTornOff(BOOL torn_off)
|
||||
mTornOff = torn_off;
|
||||
}
|
||||
|
||||
U32 LLMenuGL::getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
LLMenuItemGL* LLMenuGL::getItem(S32 number)
|
||||
{
|
||||
if (number >= 0 && number < (S32)mItems.size())
|
||||
@@ -4182,10 +4188,10 @@ S32 LLMenuBarGL::getRightmostMenuEdge()
|
||||
}
|
||||
|
||||
// add a vertical separator to this menu
|
||||
BOOL LLMenuBarGL::addSeparator()
|
||||
BOOL LLMenuBarGL::addSeparator(const std::string& name)
|
||||
{
|
||||
LLMenuItemGL* separator = new LLMenuItemVerticalSeparatorGL();
|
||||
return append( separator );
|
||||
LLMenuItemGL* separator = new LLMenuItemVerticalSeparatorGL(name);
|
||||
return append(separator);
|
||||
}
|
||||
|
||||
// add a menu - this will create a drop down menu.
|
||||
@@ -4776,7 +4782,7 @@ void LLContextMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory
|
||||
}
|
||||
else
|
||||
{
|
||||
parseChildXML(child, context, factory);
|
||||
parseChildXML(child, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5346,9 +5352,9 @@ BOOL LLPieMenu::append(LLMenuItemGL *item)
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLPieMenu::addSeparator()
|
||||
BOOL LLPieMenu::addSeparator(const std::string& name)
|
||||
{
|
||||
return append( new LLMenuItemBlankGL() );
|
||||
return append(new LLMenuItemBlankGL(name));
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
|
||||
extern S32 MENU_BAR_HEIGHT;
|
||||
extern S32 MENU_BAR_WIDTH;
|
||||
|
||||
// These callbacks are used by the LLMenuItemCallGL and LLMenuItemCheckGL
|
||||
// classes during their work.
|
||||
@@ -458,8 +457,9 @@ public:
|
||||
virtual ~LLMenuGL( void );
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
void initMenuXML(LLXMLNodePtr node, LLView* parent);
|
||||
|
||||
void parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory);
|
||||
void parseChildXML(LLXMLNodePtr child, LLView *parent);
|
||||
|
||||
// LLView Functionality
|
||||
/*virtual*/ BOOL handleUnicodeCharHere( llwchar uni_char );
|
||||
@@ -490,7 +490,7 @@ public:
|
||||
void setCanTearOff(BOOL tear_off);
|
||||
|
||||
// add a separator to this menu
|
||||
virtual BOOL addSeparator();
|
||||
virtual BOOL addSeparator(const std::string& name = LLStringUtil::null);
|
||||
|
||||
// for branching menu items, bring sub menus up to root level of menu hierarchy
|
||||
virtual void updateParent( LLView* parentp );
|
||||
@@ -527,16 +527,31 @@ public:
|
||||
|
||||
// erase group of items from menu
|
||||
void erase(S32 begin, S32 end, bool arrange = true);
|
||||
typedef std::list<LLMenuItemGL*> item_list_t;
|
||||
inline item_list_t::iterator erase(item_list_t::const_iterator first, item_list_t::const_iterator last)
|
||||
{
|
||||
for (auto it = first; it != last; ++it)
|
||||
LLUICtrl::removeChild(*it);
|
||||
return mItems.erase(first, last);
|
||||
}
|
||||
|
||||
// add new item at position
|
||||
void insert(S32 begin, LLView* ctrl, bool arrange = true);
|
||||
void insert(std::list<LLMenuItemGL*>::iterator position_iter, LLMenuItemGL* item, bool arrange = true);
|
||||
void insert(item_list_t::const_iterator position_iter, LLMenuItemGL* item, bool arrange = true);
|
||||
|
||||
// find an item's position
|
||||
std::list<LLMenuItemGL*>::iterator find(LLMenuItemGL* item) { return std::find(mItems.begin(), mItems.end(), item); }
|
||||
item_list_t::const_iterator find(LLMenuItemGL* item) const { return std::find(mItems.begin(), mItems.end(), item); }
|
||||
|
||||
// end of items, for use with other members that return an iterator
|
||||
item_list_t::const_iterator end() const { return mItems.cend(); }
|
||||
|
||||
// get list of items
|
||||
const item_list_t& getItems() const { return mItems; }
|
||||
|
||||
// number of menu items
|
||||
item_list_t::size_type getItemCount() const { return mItems.size(); }
|
||||
|
||||
void setItemLastSelected(LLMenuItemGL* item); // must be in menu
|
||||
U32 getItemCount(); // number of menu items
|
||||
LLMenuItemGL* getItem(S32 number); // 0 = first item
|
||||
LLMenuItemGL* getHighlightedItem();
|
||||
|
||||
@@ -580,18 +595,19 @@ public:
|
||||
void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; }
|
||||
bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; }
|
||||
protected:
|
||||
friend class LLTextEditor;
|
||||
void createSpilloverBranch();
|
||||
void cleanupSpilloverBranch();
|
||||
|
||||
public:
|
||||
// Add the menu item to this menu.
|
||||
virtual BOOL append( LLMenuItemGL* item );
|
||||
|
||||
// add a menu - this will create a cascading menu
|
||||
virtual BOOL appendMenu( LLMenuGL* menu );
|
||||
|
||||
// TODO: create accessor methods for these?
|
||||
typedef std::list< LLMenuItemGL* > item_list_t;
|
||||
protected:
|
||||
item_list_t mItems;
|
||||
// TODO: create accessor methods for these?
|
||||
LLMenuItemGL*mFirstVisibleItem;
|
||||
LLMenuItemGL *mArrowUpItem, *mArrowDownItem;
|
||||
|
||||
@@ -762,7 +778,7 @@ public:
|
||||
private:
|
||||
virtual BOOL append(LLMenuItemGL* item);
|
||||
public:
|
||||
virtual BOOL addSeparator();
|
||||
virtual BOOL addSeparator(const std::string& name = LLStringUtil::null) override final;
|
||||
|
||||
virtual void arrange( void );
|
||||
|
||||
@@ -842,7 +858,7 @@ public:
|
||||
/*virtual*/ BOOL jumpKeysActive();
|
||||
|
||||
// add a vertical separator to this menu
|
||||
virtual BOOL addSeparator();
|
||||
virtual BOOL addSeparator(const std::string& name = LLStringUtil::null) override final;
|
||||
|
||||
// LLView Functionality
|
||||
virtual BOOL handleHover( S32 x, S32 y, MASK mask );
|
||||
@@ -894,6 +910,7 @@ public:
|
||||
LLView*const getVisibleMenu() const;
|
||||
virtual BOOL hasVisibleMenu() const {return getVisibleMenu() != NULL;}
|
||||
|
||||
static LLMenuItemGL* getActivatedItem() { return static_cast<LLMenuItemGL*>(sItemLastSelectedHandle.get()); }
|
||||
static void setActivatedItem(LLMenuItemGL* item);
|
||||
|
||||
// Need to detect if mouse-up after context menu spawn has moved.
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llscrollbar.cpp
|
||||
* @brief Scrollbar UI widget
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* 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.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -46,6 +40,7 @@
|
||||
#include "llwindow.h"
|
||||
#include "llcontrol.h"
|
||||
#include "llrender.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
LLScrollbar::LLScrollbar(
|
||||
const std::string& name, LLRect rect,
|
||||
@@ -402,7 +397,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
|
||||
}
|
||||
|
||||
getWindow()->setCursor(UI_CURSOR_ARROW);
|
||||
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (active)" << LL_ENDL;
|
||||
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (active)" << LL_ENDL;
|
||||
handled = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -414,7 +409,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
|
||||
if( !handled )
|
||||
{
|
||||
getWindow()->setCursor(UI_CURSOR_ARROW);
|
||||
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL;
|
||||
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL;
|
||||
handled = TRUE;
|
||||
}
|
||||
|
||||
@@ -468,6 +463,13 @@ BOOL LLScrollbar::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
return handled;
|
||||
}
|
||||
|
||||
BOOL LLScrollbar::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
// just treat a double click as a second click
|
||||
return handleMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
|
||||
void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
if (width == getRect().getWidth() && height == getRect().getHeight()) return;
|
||||
@@ -509,7 +511,6 @@ void LLScrollbar::draw()
|
||||
mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLSmoothInterpolation::getInterpolant(0.05f));
|
||||
}
|
||||
|
||||
|
||||
// Draw background and thumb.
|
||||
LLUIImage* rounded_rect_imagep = LLUI::getUIImage("Rounded_Square");
|
||||
|
||||
@@ -525,6 +526,9 @@ void LLScrollbar::draw()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Thumb
|
||||
LLRect outline_rect = mThumbRect;
|
||||
outline_rect.stretch(2);
|
||||
// Background
|
||||
rounded_rect_imagep->drawSolid(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0,
|
||||
mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0,
|
||||
@@ -532,9 +536,6 @@ void LLScrollbar::draw()
|
||||
mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
|
||||
mTrackColor);
|
||||
|
||||
// Thumb
|
||||
LLRect outline_rect = mThumbRect;
|
||||
outline_rect.stretch(2);
|
||||
|
||||
if (gFocusMgr.getKeyboardFocus() == this)
|
||||
{
|
||||
@@ -636,3 +637,8 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
|
||||
{
|
||||
changeLine( mStepSize, TRUE );
|
||||
}
|
||||
|
||||
void LLScrollbar::setThickness(S32 thickness)
|
||||
{
|
||||
mThickness = thickness < 0 ? SCROLLBAR_SIZE : thickness;
|
||||
}
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llscrollbar.h
|
||||
* @brief Scrollbar UI widget
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -36,6 +30,7 @@
|
||||
#include "stdtypes.h"
|
||||
#include "lluictrl.h"
|
||||
#include "v4color.h"
|
||||
#include "llbutton.h"
|
||||
|
||||
//
|
||||
// Constants
|
||||
@@ -59,6 +54,7 @@ public:
|
||||
callback_t change_callback,
|
||||
S32 step_size = 1);
|
||||
|
||||
public:
|
||||
virtual ~LLScrollbar();
|
||||
|
||||
virtual void setValue(const LLSD& value);
|
||||
@@ -67,6 +63,7 @@ public:
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
@@ -104,6 +101,9 @@ public:
|
||||
void onLineUpBtnPressed(const LLSD& data);
|
||||
void onLineDownBtnPressed(const LLSD& data);
|
||||
|
||||
S32 getThickness() const { return mThickness; }
|
||||
void setThickness(S32 thickness);
|
||||
|
||||
void setTrackColor( const LLColor4& color ) { mTrackColor = color; }
|
||||
void setThumbColor( const LLColor4& color ) { mThumbColor = color; }
|
||||
void setHighlightColor( const LLColor4& color ) { mHighlightColor = color; }
|
||||
@@ -145,5 +145,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // LL_SCROLLBAR_H
|
||||
|
||||
@@ -218,6 +218,15 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLScrollContainer::handleUnicodeCharHere(llwchar uni_char)
|
||||
{
|
||||
if (mScrolledView && mScrolledView->handleUnicodeCharHere(uni_char))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks )
|
||||
{
|
||||
// Give event to my child views - they may have scroll bars
|
||||
@@ -262,7 +271,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
{
|
||||
//S32 scrollbar_size = SCROLLBAR_SIZE;
|
||||
// Scroll folder view if needed. Never accepts a drag or drop.
|
||||
*accept = ACCEPT_NO;
|
||||
BOOL handled = autoScroll(x, y);
|
||||
@@ -413,6 +421,7 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLScrollContainer::draw()
|
||||
{
|
||||
S32 scrollbar_size = SCROLLBAR_SIZE;
|
||||
@@ -525,7 +534,7 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group)
|
||||
|
||||
void LLScrollContainer::updateScroll()
|
||||
{
|
||||
if (!mScrolledView)
|
||||
if (!getVisible() || !mScrolledView)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -626,6 +635,7 @@ LLRect LLScrollContainer::getVisibleContentRect()
|
||||
visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom);
|
||||
return visible_rect;
|
||||
}
|
||||
|
||||
LLRect LLScrollContainer::getContentWindowRect()
|
||||
{
|
||||
updateScroll();
|
||||
@@ -729,6 +739,13 @@ S32 LLScrollContainer::getBorderWidth() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LLScrollContainer::setSize(S32 size)
|
||||
{
|
||||
mSize = size;
|
||||
mScrollbar[VERTICAL]->setThickness(size);
|
||||
mScrollbar[HORIZONTAL]->setThickness(size);
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLXMLNodePtr LLScrollContainer::getXML(bool save_children) const
|
||||
{
|
||||
@@ -801,7 +818,7 @@ LLView* LLScrollContainer::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFa
|
||||
panelp = new LLPanel(std::string("dummy"), LLRect::null, FALSE);
|
||||
}
|
||||
|
||||
ret->mScrolledView = panelp;
|
||||
ret->addChild(panelp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llscrollcontainer.h
|
||||
* @brief LLScrollContainer class header file.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -78,7 +72,7 @@ public:
|
||||
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
|
||||
LLRect getVisibleContentRect();
|
||||
LLRect getContentWindowRect();
|
||||
const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
|
||||
virtual const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
|
||||
void pageUp(S32 overlap = 0);
|
||||
void pageDown(S32 overlap = 0);
|
||||
void goToTop();
|
||||
@@ -90,6 +84,7 @@ public:
|
||||
// LLView functionality
|
||||
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
|
||||
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
@@ -105,9 +100,14 @@ public:
|
||||
virtual LLXMLNodePtr getXML(bool save_children) const;
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
|
||||
S32 getSize() const { return mSize; }
|
||||
void setSize(S32 thickness);
|
||||
|
||||
protected:
|
||||
LLView* mScrolledView;
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
// internal scrollbar handlers
|
||||
virtual void scrollHorizontal( S32 new_pos );
|
||||
virtual void scrollVertical( S32 new_pos );
|
||||
@@ -117,7 +117,6 @@ public:
|
||||
private:
|
||||
|
||||
LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
|
||||
LLView* mScrolledView;
|
||||
S32 mSize;
|
||||
BOOL mIsOpaque;
|
||||
LLColor4 mBackgroundColor;
|
||||
|
||||
@@ -59,8 +59,6 @@
|
||||
|
||||
static LLRegisterWidget<LLScrollListCtrl> r("scroll_list");
|
||||
|
||||
std::vector<LLMenuGL*> LLScrollListCtrl::sMenus = {}; // List menus that recur, such as general avatars or groups menus
|
||||
|
||||
// local structures & classes.
|
||||
struct SortScrollListItem
|
||||
{
|
||||
@@ -314,7 +312,7 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
uuid_vec_t LLScrollListCtrl::getSelectedIDs()
|
||||
uuid_vec_t LLScrollListCtrl::getSelectedIDs() const
|
||||
{
|
||||
uuid_vec_t ids;
|
||||
if (!getCanSelect()) return ids;
|
||||
@@ -1813,10 +1811,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
if (col->mHeader && col->mHeader->getRect().pointInRect(x,y)) // Right clicking a column header shouldn't bring up a menu
|
||||
return FALSE;
|
||||
}
|
||||
gFocusMgr.setKeyboardFocus(this); // Menu listeners rely on this
|
||||
mPopupMenu->buildDrawLabels();
|
||||
mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, mPopupMenu, x, y);
|
||||
showMenu(this, mPopupMenu, x, y);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2041,6 +2036,11 @@ void LLScrollListCtrl::setFilter(const std::string& filter)
|
||||
adjustScrollbar(unfiltered_count);
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::setContextMenu(const std::string& menu)
|
||||
{
|
||||
setContextMenu(LLUICtrlFactory::instance().buildMenu(menu, LLMenuGL::sMenuContainer));
|
||||
}
|
||||
|
||||
|
||||
BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
|
||||
{
|
||||
@@ -2700,61 +2700,43 @@ void LLScrollListCtrl::setScrollListParameters(LLXMLNodePtr node)
|
||||
|
||||
if (node->hasAttribute("menu_num"))
|
||||
{
|
||||
// Some scroll lists use common menus identified by number
|
||||
// 0 is menu_avs_list.xml, 1 will be for groups, 2 could be for lists of objects
|
||||
// Some UI uses common menus identified by number
|
||||
// 0 is avatars, 1 will be for groups, others could be for lists of objects or locations or experiences
|
||||
S32 menu_num;
|
||||
node->getAttributeS32("menu_num", menu_num);
|
||||
setContextMenu(menu_num);
|
||||
mPopupMenu = sMenus[menu_num];
|
||||
}
|
||||
else if (node->hasAttribute("menu_file"))
|
||||
{
|
||||
std::string menu_file;
|
||||
node->getAttributeString("menu_file", menu_file);
|
||||
mPopupMenu = LLUICtrlFactory::getInstance()->buildMenu(menu_file, LLMenuGL::sMenuContainer);
|
||||
std::string menu;
|
||||
node->getAttributeString("menu_file", menu);
|
||||
if (!menu.empty()) setContextMenu(menu);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
LLRect rect;
|
||||
createRect(node, rect, parent, LLRect());
|
||||
|
||||
BOOL multi_select = false;
|
||||
node->getAttributeBOOL("multi_select", multi_select);
|
||||
BOOL draw_border = true;
|
||||
node->getAttributeBOOL("draw_border", draw_border);
|
||||
BOOL draw_heading = false;
|
||||
node->getAttributeBOOL("draw_heading", draw_heading);
|
||||
S32 search_column = 0;
|
||||
node->getAttributeS32("search_column", search_column);
|
||||
S32 sort_column = -1;
|
||||
node->getAttributeS32("sort_column", sort_column);
|
||||
BOOL sort_ascending = true;
|
||||
node->getAttributeBOOL("sort_ascending", sort_ascending);
|
||||
|
||||
LLScrollListCtrl* scroll_list = new LLScrollListCtrl("scroll_list", rect, NULL, multi_select, draw_border, draw_heading);
|
||||
|
||||
if (node->hasAttribute("heading_height"))
|
||||
{
|
||||
S32 heading_height;
|
||||
node->getAttributeS32("heading_height", heading_height);
|
||||
scroll_list->setHeadingHeight(heading_height);
|
||||
setHeadingHeight(heading_height);
|
||||
}
|
||||
|
||||
scroll_list->setScrollListParameters(node);
|
||||
scroll_list->initFromXML(node, parent);
|
||||
scroll_list->setSearchColumn(search_column);
|
||||
S32 search_column = 0;
|
||||
node->getAttributeS32("search_column", search_column);
|
||||
BOOL sort_ascending = true;
|
||||
node->getAttributeBOOL("sort_ascending", sort_ascending);
|
||||
|
||||
setSearchColumn(search_column);
|
||||
|
||||
LLSD columns;
|
||||
S32 index = 0;
|
||||
const std::string nodename(std::string(node->getName()->mString) + '.');
|
||||
const std::string kidcolumn(nodename + "columns");
|
||||
const std::string kidcolumns(nodename + "columns");
|
||||
const std::string kidcolumn(nodename + "column");
|
||||
for (LLXMLNodePtr child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
|
||||
{
|
||||
if (child->hasName("column") || child->hasName(kidcolumn))
|
||||
if (child->hasName("column") || child->hasName("columns") || child->hasName(kidcolumn) || child->hasName(kidcolumns))
|
||||
{
|
||||
std::string labelname("");
|
||||
std::string labelname;
|
||||
if (child->getAttributeString("label", labelname))
|
||||
columns[index]["label"] = labelname;
|
||||
else if (child->getAttributeString("image", labelname))
|
||||
@@ -2777,9 +2759,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
||||
}
|
||||
else // Singu Note: if a scroll list does not provide sort_direction, provide sort_ascending to sort as expected
|
||||
{
|
||||
bool sort_ascending = true;
|
||||
child->getAttribute_bool("sort_ascending", sort_ascending);
|
||||
columns[index]["sort_ascending"] = sort_ascending;
|
||||
bool col_sort_ascending = sort_ascending;
|
||||
child->getAttribute_bool("sort_ascending", col_sort_ascending);
|
||||
columns[index]["sort_ascending"] = col_sort_ascending;
|
||||
}
|
||||
|
||||
S32 columnwidth = -1;
|
||||
@@ -2805,12 +2787,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
||||
++index;
|
||||
}
|
||||
}
|
||||
scroll_list->setColumnHeadings(columns);
|
||||
|
||||
if (sort_column >= 0)
|
||||
{
|
||||
scroll_list->sortByColumnIndex(sort_column, sort_ascending);
|
||||
}
|
||||
setColumnHeadings(columns);
|
||||
|
||||
const std::string kidrow(nodename + "row");
|
||||
const std::string kidrows(nodename + "rows");
|
||||
@@ -2832,9 +2809,10 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
||||
bool explicit_column = false;
|
||||
for (LLXMLNodePtr row_child = child->getFirstChild(); row_child.notNull(); row_child = row_child->getNextSibling())
|
||||
{
|
||||
if (row_child->hasName("column"))
|
||||
if (row_child->hasName("column") || row_child->hasName("columns"))
|
||||
{
|
||||
std::string value = row_child->getTextContents();
|
||||
row_child->getAttributeString("value", value);
|
||||
row["columns"][column_idx]["value"] = value;
|
||||
|
||||
std::string columnname;
|
||||
@@ -2854,25 +2832,53 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
||||
}
|
||||
}
|
||||
if(explicit_column)
|
||||
scroll_list->addElement(row);
|
||||
addElement(row);
|
||||
else
|
||||
{
|
||||
LLSD entry_id;
|
||||
if(id_found)
|
||||
entry_id = id;
|
||||
scroll_list->addSimpleElement(value,ADD_BOTTOM,entry_id);
|
||||
addSimpleElement(value,ADD_BOTTOM,entry_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scroll_list->setCommentText(node->getTextContents());
|
||||
S32 sort_column = -1;
|
||||
node->getAttributeS32("sort_column", sort_column);
|
||||
if (sort_column >= 0)
|
||||
{
|
||||
sortByColumnIndex(sort_column, sort_ascending);
|
||||
}
|
||||
|
||||
setCommentText(node->getTextContents());
|
||||
}
|
||||
|
||||
// static
|
||||
LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
LLRect rect;
|
||||
createRect(node, rect, parent, LLRect());
|
||||
|
||||
BOOL multi_select = false;
|
||||
node->getAttributeBOOL("multi_select", multi_select);
|
||||
|
||||
BOOL draw_border = true;
|
||||
node->getAttributeBOOL("draw_border", draw_border);
|
||||
|
||||
BOOL draw_heading = false;
|
||||
node->getAttributeBOOL("draw_heading", draw_heading);
|
||||
|
||||
LLScrollListCtrl* scroll_list = new LLScrollListCtrl("scroll_list", rect, NULL, multi_select, draw_border, draw_heading);
|
||||
|
||||
scroll_list->setScrollListParameters(node);
|
||||
scroll_list->initFromXML(node, parent);
|
||||
return scroll_list;
|
||||
}
|
||||
|
||||
// LLEditMenuHandler functions
|
||||
|
||||
// virtual
|
||||
void LLScrollListCtrl::copy()
|
||||
void LLScrollListCtrl::copy() const
|
||||
{
|
||||
std::string buffer;
|
||||
for (auto item : getAllSelected())
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
||||
#include "lfidbearer.h"
|
||||
#include "lluictrl.h"
|
||||
#include "llctrlselectioninterface.h"
|
||||
#include "llfontgl.h"
|
||||
@@ -48,6 +49,7 @@ class LLMenuGL;
|
||||
|
||||
class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
|
||||
public LLCtrlListInterface, public LLCtrlScrollInterface
|
||||
, public LFIDBearer
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void (void)> callback_t;
|
||||
@@ -194,12 +196,12 @@ public:
|
||||
// "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
|
||||
// has an associated, unique UUID, and only one of which can be selected at a time.
|
||||
LLScrollListItem* addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE);
|
||||
LLUUID getStringUUIDSelectedItem() const;
|
||||
LLUUID getStringUUIDSelectedItem() const override final;
|
||||
|
||||
LLScrollListItem* getFirstSelected() const;
|
||||
virtual S32 getFirstSelectedIndex() const;
|
||||
std::vector<LLScrollListItem*> getAllSelected() const;
|
||||
uuid_vec_t getSelectedIDs(); //Helper. Much like getAllSelected, but just provides a LLUUID vec
|
||||
uuid_vec_t getSelectedIDs() const override final; //Helper. Much like getAllSelected, but just provides a LLUUID vec
|
||||
S32 getNumSelected() const;
|
||||
LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
|
||||
|
||||
@@ -252,10 +254,18 @@ public:
|
||||
bool filterItem(LLScrollListItem* item);
|
||||
void setFilter(const std::string& filter);
|
||||
|
||||
// support right-click context menus for avatar/group lists
|
||||
// Context Menus
|
||||
void setContextMenu(LLMenuGL* menu) { mPopupMenu = menu; }
|
||||
void setContextMenu(S32 index) { mPopupMenu = sMenus[index]; }
|
||||
static void addCommonMenu(LLMenuGL* menu) { sMenus.push_back(menu); }
|
||||
void setContextMenu(U8 index) { mPopupMenu = sMenus[index]; }
|
||||
void setContextMenu(const std::string& menu);
|
||||
|
||||
Type getSelectedType() const override
|
||||
{
|
||||
for (auto i = 0; mPopupMenu && i < COUNT; ++i)
|
||||
if (sMenus[i] == mPopupMenu)
|
||||
return (Type)i;
|
||||
return LFIDBearer::getSelectedType();
|
||||
}
|
||||
|
||||
// Overridden from LLView
|
||||
/*virtual*/ void draw();
|
||||
@@ -312,7 +322,7 @@ public:
|
||||
virtual void scrollToShowSelected();
|
||||
|
||||
// LLEditMenuHandler functions
|
||||
virtual void copy();
|
||||
void copy() const override final;
|
||||
virtual BOOL canCopy() const;
|
||||
virtual void cut();
|
||||
virtual BOOL canCut() const;
|
||||
@@ -468,8 +478,6 @@ private:
|
||||
class LLViewBorder* mBorder;
|
||||
LLMenuGL *mPopupMenu;
|
||||
|
||||
static std::vector<LLMenuGL*> sMenus; // List menus that recur, such as general avatars or groups menus
|
||||
|
||||
LLView *mCommentTextView;
|
||||
|
||||
LLWString mSearchString;
|
||||
|
||||
@@ -1896,3 +1896,8 @@ void LLTabContainer::commitHoveredButton(S32 x, S32 y)
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLTabContainer::getTotalTabWidth() const
|
||||
{
|
||||
return mTotalTabWidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ public:
|
||||
S32 getIndexForPanel(LLPanel* panel);
|
||||
S32 getPanelIndexByTitle(const std::string& title);
|
||||
LLPanel* getPanelByName(const std::string& name);
|
||||
S32 getTotalTabWidth() const;
|
||||
void setCurrentTabName(const std::string& name);
|
||||
|
||||
void selectFirstTab();
|
||||
|
||||
@@ -113,6 +113,7 @@ private:
|
||||
void setLineLengths();
|
||||
void drawText(S32 x, S32 y, const LLColor4& color );
|
||||
|
||||
protected:
|
||||
LLUIString mText;
|
||||
const LLFontGL* mFontGL;
|
||||
LLColor4 mTextColor;
|
||||
|
||||
@@ -244,8 +244,6 @@ private:
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
LLTextEditor::is_friend_signal_t* LLTextEditor::mIsFriendSignal = nullptr;
|
||||
LLTextEditor::is_blocked_signal_t* LLTextEditor::mIsObjectBlockedSignal = nullptr;
|
||||
|
||||
LLTextEditor::LLTextEditor(
|
||||
const std::string& name,
|
||||
@@ -372,57 +370,64 @@ LLTextEditor::~LLTextEditor()
|
||||
menu->die();
|
||||
mPopupMenuHandle.markDead();
|
||||
}
|
||||
/* Singu Note: Static this, we'll use it wherever we can!
|
||||
delete mIsFriendSignal;
|
||||
delete mIsObjectBlockedSignal;*/
|
||||
}
|
||||
|
||||
const std::string& LLTextEditor::getMenuSegmentUrl() const
|
||||
{
|
||||
auto segment = getSegmentAtLocalPos(mLastContextMenuX, mLastContextMenuY);
|
||||
auto style = segment->getStyle();
|
||||
auto style = segment ? segment->getStyle() : nullptr;
|
||||
return style ? style->getLinkHREF() : LLStringUtil::null;
|
||||
}
|
||||
|
||||
static LLTextEditor* get_focused_text_editor()
|
||||
static LFIDBearer::Type get_type_from_url(const std::string& url)
|
||||
{
|
||||
auto* te =
|
||||
#ifdef SHOW_ASSERT
|
||||
dynamic_cast<LLTextEditor*>
|
||||
#else
|
||||
static_cast<LLTextEditor*>
|
||||
#endif
|
||||
(gFocusMgr.getKeyboardFocus());
|
||||
llassert(te); // This listener only applies to text editors
|
||||
return te;
|
||||
auto pos = url.find("/app/");
|
||||
if (pos != std::string::npos && pos + 10 <= url.size())
|
||||
{
|
||||
auto type = url.substr(pos + 5, 5);
|
||||
return type == "agent" ? LFIDBearer::AVATAR
|
||||
: type == "group" ? LFIDBearer::GROUP
|
||||
: type == "experience" ? LFIDBearer::EXPERIENCE
|
||||
: LFIDBearer::OBJECT;
|
||||
}
|
||||
return LFIDBearer::NONE;
|
||||
}
|
||||
|
||||
class ContextText : public LLMemberListener<LLView>
|
||||
LLUUID LLTextEditor::getStringUUIDSelectedItem() const
|
||||
{
|
||||
const auto& url = getMenuSegmentUrl();
|
||||
const auto& type = get_type_from_url(url);
|
||||
return type == LFIDBearer::NONE ? LLUUID::null : LLUUID(type == OBJECT ? LLUrlAction::getObjectId(url) : LLUrlAction::getUserID(url));
|
||||
}
|
||||
|
||||
LFIDBearer::Type LLTextEditor::getSelectedType() const
|
||||
{
|
||||
return get_type_from_url(getMenuSegmentUrl());
|
||||
}
|
||||
|
||||
class CopyRawText : public LLMemberListener<LLView>
|
||||
{
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent>, const LLSD& userdata) override
|
||||
{
|
||||
auto text = get_focused_text_editor();
|
||||
const auto& op = userdata.asStringRef();
|
||||
if (op == "Cut") text->cut();
|
||||
else if (op == "Copy") text->copy();
|
||||
else if (op == "CopyRaw") text->copyRaw();
|
||||
else if (op == "Paste") text->paste();
|
||||
else if (op == "Delete") text->doDelete();
|
||||
else if (op == "SelectAll") text->selectAll();
|
||||
LFIDBearer::getActive<LLTextEditor>()->copyRaw();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static const std::string& get_focused_url()
|
||||
class TextEditorVisible : public LLMemberListener<LLView>
|
||||
{
|
||||
return get_focused_text_editor()->getMenuSegmentUrl();
|
||||
}
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent>, const LLSD& userdata) override
|
||||
{
|
||||
LLMenuGL::sMenuContainer->findControl(userdata["control"].asString())->setValue(!!dynamic_cast<LLTextEditor*>(gFocusMgr.getKeyboardFocus()));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ContextUrl : public LLMemberListener<LLView>
|
||||
{
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent>, const LLSD& userdata) override
|
||||
{
|
||||
const auto& url = get_focused_url();
|
||||
const auto& url = LFIDBearer::getActive<LLTextEditor>()->getMenuSegmentUrl();
|
||||
const auto& op = userdata.asStringRef();
|
||||
if (op == "Open") LLUrlAction::openURL(url);
|
||||
else if (op == "OpenInternal") LLUrlAction::openURLInternal(url);
|
||||
@@ -431,10 +436,6 @@ class ContextUrl : public LLMemberListener<LLView>
|
||||
else if (op == "Block") LLUrlAction::blockObject(url);
|
||||
else if (op == "Unblock") LLUrlAction::unblockObject(url);
|
||||
else if (op == "Teleport") LLUrlAction::teleportToLocation(url);
|
||||
else if (op == "ShowProfile") LLUrlAction::showProfile(url);
|
||||
else if (op == "AddFriend") LLUrlAction::addFriend(url);
|
||||
else if (op == "RemoveFriend") LLUrlAction::removeFriend(url);
|
||||
else if (op == "SendIM") LLUrlAction::sendIM(url);
|
||||
else if (op == "ShowOnMap") LLUrlAction::showLocationOnMap(url);
|
||||
else if (op == "CopyLabel") LLUrlAction::copyLabelToClipboard(url);
|
||||
else if (op == "CopyUrl") LLUrlAction::copyURLToClipboard(url);
|
||||
@@ -442,90 +443,35 @@ class ContextUrl : public LLMemberListener<LLView>
|
||||
}
|
||||
};
|
||||
|
||||
class ContextIDUrl : public LLMemberListener<LLView>
|
||||
{
|
||||
protected:
|
||||
std::string getID(const std::string& type) const
|
||||
{
|
||||
const auto& url = get_focused_url();
|
||||
// Empty works like avatar and group, "object" is an object (you needed to be told this)
|
||||
return type.empty() ? LLUrlAction::getUserID(url) : LLUrlAction::getObjectId(url);
|
||||
}
|
||||
};
|
||||
|
||||
class ContextUrlCopy : public ContextIDUrl
|
||||
class ContextUrlCopy : public LLMemberListener<LLView>
|
||||
{
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent>, const LLSD& userdata) override
|
||||
{
|
||||
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(getID(userdata.asStringRef())));
|
||||
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(LFIDBearer::getActiveSelectedID().asString()));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ContextUrlExt : public ContextIDUrl
|
||||
{
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent>, const LLSD& userdata) override
|
||||
{
|
||||
std::string cmd = userdata.asStringRef();
|
||||
std::string type;
|
||||
const auto sep = cmd.find(',');
|
||||
if (sep != std::string::npos)
|
||||
{
|
||||
type = cmd.substr(sep);
|
||||
cmd = cmd.substr(0, sep);
|
||||
}
|
||||
mExtCallback(cmd, LLUUID(getID(type)));
|
||||
return true;
|
||||
}
|
||||
LLTextEditor::ext_slurl_cb mExtCallback;
|
||||
public:
|
||||
ContextUrlExt(LLTextEditor::ext_slurl_cb cb) : mExtCallback(cb) {}
|
||||
};
|
||||
|
||||
class ContextUrlExtVisible : public ContextIDUrl
|
||||
{
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent>, const LLSD& userdata) override
|
||||
{
|
||||
std::string cmd = userdata["data"];
|
||||
std::string type;
|
||||
const auto sep = cmd.find(',');
|
||||
if (sep != std::string::npos)
|
||||
{
|
||||
type = cmd.substr(sep);
|
||||
cmd = cmd.substr(0, sep);
|
||||
}
|
||||
|
||||
LLMenuGL::sMenuContainer->findControl(userdata["control"].asString())->setValue(mExtVCB(cmd, LLUUID(getID(type))));
|
||||
return true;
|
||||
}
|
||||
LLTextEditor::ext_slurl_visible_cb mExtVCB;
|
||||
public:
|
||||
ContextUrlExtVisible(LLTextEditor::ext_slurl_visible_cb vcb) : mExtVCB(vcb) {}
|
||||
};
|
||||
|
||||
|
||||
void LLTextEditor::spell_correct(void* data)
|
||||
{
|
||||
SpellMenuBind* tempBind = (SpellMenuBind*)data;
|
||||
LLTextEditor* line = tempBind->origin;
|
||||
if(tempBind && line)
|
||||
auto self = static_cast<LLTextEditor*>(data);
|
||||
S32 wordStart = 0, wordLen = 0;
|
||||
if (self->getWordBoundriesAt(self->getCursorPosFromLocalCoord(self->mLastContextMenuX, self->mLastContextMenuY, TRUE), &wordStart, &wordLen))
|
||||
{
|
||||
LL_INFOS() << tempBind->menuItem->getName() << " : " << tempBind->origin->getName() << " : " << tempBind->word << LL_ENDL;
|
||||
if(line)line->spellReplace(tempBind);
|
||||
const auto& word = utf8str_to_wstring(LLMenuGL::sMenuContainer->getActivatedItem()->getLabel());
|
||||
|
||||
self->remove(wordStart, wordLen, TRUE);
|
||||
self->insert(wordStart, word, FALSE);
|
||||
self->mCursorPos += word.length() - wordLen;
|
||||
self->needsReflow();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLTextEditor::spell_show(void * data)
|
||||
void LLTextEditor::spell_show(void* show)
|
||||
{
|
||||
SpellMenuBind* tempBind = (SpellMenuBind*)data;
|
||||
LLTextEditor* line = tempBind->origin;
|
||||
|
||||
if(tempBind && line)
|
||||
{
|
||||
BOOL show = (tempBind->word == "Show Misspellings");
|
||||
glggHunSpell->setSpellCheckHighlight(show);
|
||||
}
|
||||
glggHunSpell->setSpellCheckHighlight(!!show);
|
||||
}
|
||||
|
||||
|
||||
@@ -572,22 +518,22 @@ std::vector<S32> LLTextEditor::getMisspelledWordsPositions()
|
||||
|
||||
void LLTextEditor::spell_add(void* data)
|
||||
{
|
||||
SpellMenuBind* tempBind = (SpellMenuBind*)data;
|
||||
if(tempBind)
|
||||
auto self = static_cast<LLTextEditor*>(data);
|
||||
S32 wordStart = 0, wordLen = 0;
|
||||
if (self->getWordBoundriesAt(self->getCursorPosFromLocalCoord(self->mLastContextMenuX, self->mLastContextMenuY, TRUE), &wordStart, &wordLen))
|
||||
{
|
||||
glggHunSpell->addWordToCustomDictionary(tempBind->word);
|
||||
tempBind->origin->mPrevSpelledText.erase();//make it update
|
||||
glggHunSpell->addWordToCustomDictionary(wstring_to_utf8str(self->getWText().substr(wordStart, wordLen)));
|
||||
self->mPrevSpelledText.erase(); //make it update
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLTextEditor::addMenuListeners(ext_slurl_cb cb, ext_slurl_visible_cb vcb)
|
||||
void LLTextEditor::addMenuListeners()
|
||||
{
|
||||
(new ContextText)->registerListener(LLMenuGL::sMenuContainer, "Text");
|
||||
(new CopyRawText)->registerListener(LLMenuGL::sMenuContainer, "CopyRawText");
|
||||
(new TextEditorVisible)->registerListener(LLMenuGL::sMenuContainer, "TextEditorVisible");
|
||||
(new ContextUrl)->registerListener(LLMenuGL::sMenuContainer, "Text.Url");
|
||||
(new ContextUrlCopy)->registerListener(LLMenuGL::sMenuContainer, "Text.Url.CopyUUID");
|
||||
(new ContextUrlExt(cb))->registerListener(LLMenuGL::sMenuContainer, "Text.Url.Ext");
|
||||
(new ContextUrlExtVisible(vcb))->registerListener(LLMenuGL::sMenuContainer, "Text.Url.ExtVisible");
|
||||
}
|
||||
|
||||
void LLTextEditor::setTrackColor( const LLColor4& color )
|
||||
@@ -765,35 +711,7 @@ LLMenuGL* LLTextEditor::createUrlContextMenu(S32 x, S32 y, const std::string &in
|
||||
|
||||
// create and return the context menu from the XUI file
|
||||
llassert(LLMenuGL::sMenuContainer != NULL);
|
||||
auto menu = LLUICtrlFactory::getInstance()->buildMenu(xui_file, LLMenuGL::sMenuContainer);
|
||||
if (menu)
|
||||
{
|
||||
if (mIsFriendSignal)
|
||||
{
|
||||
bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
|
||||
LLView* addFriendButton = menu->findChild<LLView>("add_friend");
|
||||
LLView* removeFriendButton = menu->findChild<LLView>("remove_friend");
|
||||
|
||||
if (addFriendButton && removeFriendButton)
|
||||
{
|
||||
addFriendButton->setVisible(!isFriend);
|
||||
removeFriendButton->setVisible(isFriend);
|
||||
}
|
||||
}
|
||||
|
||||
if (mIsObjectBlockedSignal)
|
||||
{
|
||||
bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
|
||||
LLView* blockButton = menu->findChild<LLView>("block_object");
|
||||
LLView* unblockButton = menu->findChild<LLView>("unblock_object");
|
||||
|
||||
if (blockButton && unblockButton)
|
||||
{
|
||||
blockButton->setVisible(!is_blocked);
|
||||
unblockButton->setVisible(is_blocked);
|
||||
}
|
||||
}
|
||||
}
|
||||
auto menu = LLUICtrlFactory::instance().buildMenu(xui_file, LLMenuGL::sMenuContainer);
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -1528,35 +1446,13 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
}
|
||||
BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
|
||||
{
|
||||
|
||||
setFocus(TRUE);
|
||||
|
||||
//setCursorAtLocalPos( x, y, TRUE );
|
||||
S32 wordStart = 0;
|
||||
S32 wordLen = 0;
|
||||
S32 pos = getCursorPosFromLocalCoord(x,y,TRUE);
|
||||
|
||||
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
|
||||
if (menu)
|
||||
{
|
||||
for (auto tempBind : suggestionMenuItems)
|
||||
{
|
||||
if (tempBind)
|
||||
{
|
||||
menu->removeChild(tempBind->menuItem);
|
||||
tempBind->menuItem->die();
|
||||
delete tempBind;
|
||||
}
|
||||
}
|
||||
suggestionMenuItems.clear();
|
||||
menu->die();
|
||||
}
|
||||
|
||||
auto segment = getSegmentAtLocalPos(x, y);
|
||||
const LLStyleSP style = segment ? segment->getStyle() : nullptr;
|
||||
auto submenu = (style && style->isLink()) ? createUrlContextMenu(x, y, style->getLinkHREF()) : nullptr;
|
||||
// Add url menu to base menu if we have a selection, otherwise make it the menu.
|
||||
menu = (submenu && !hasSelection()) ? submenu : LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", LLMenuGL::sMenuContainer);
|
||||
auto menu = (submenu && !hasSelection()) ? submenu : LLUICtrlFactory::instance().buildMenu("menu_texteditor.xml", LLMenuGL::sMenuContainer);
|
||||
mPopupMenuHandle = menu->getHandle();
|
||||
if (menu)
|
||||
{
|
||||
@@ -1569,69 +1465,34 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
|
||||
// spell_check="true" in xui
|
||||
if (!mReadOnly && mSpellCheckable)
|
||||
{
|
||||
bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen);
|
||||
if (is_word_part)
|
||||
S32 wordStart = 0;
|
||||
S32 wordLen = 0;
|
||||
S32 pos = getCursorPosFromLocalCoord(x, y, TRUE);
|
||||
if (getWordBoundriesAt(pos, &wordStart, &wordLen))
|
||||
{
|
||||
const LLWString &text = mWText;
|
||||
std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart, wordLen));
|
||||
const auto selectedWord = wstring_to_utf8str(getWText().substr(wordStart, wordLen));
|
||||
|
||||
if (!glggHunSpell->isSpelledRight(selectedWord))
|
||||
{
|
||||
//misspelled word here, and you have just right clicked on it!
|
||||
std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
|
||||
|
||||
menu->addSeparator();
|
||||
for (auto word : suggs)
|
||||
for (const auto& word : glggHunSpell->getSuggestionList(selectedWord))
|
||||
{
|
||||
SpellMenuBind * tempStruct = new SpellMenuBind;
|
||||
tempStruct->origin = this;
|
||||
tempStruct->word = word;
|
||||
tempStruct->wordPositionEnd = wordStart + wordLen;
|
||||
tempStruct->wordPositionStart = wordStart;
|
||||
tempStruct->wordY = y;
|
||||
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
|
||||
tempStruct->word, spell_correct, NULL, tempStruct);
|
||||
tempStruct->menuItem = suggMenuItem;
|
||||
suggestionMenuItems.push_back(tempStruct);
|
||||
menu->addChild(suggMenuItem);
|
||||
menu->addChild(new LLMenuItemCallGL(word, spell_correct, nullptr, this));
|
||||
}
|
||||
SpellMenuBind * tempStruct = new SpellMenuBind;
|
||||
tempStruct->origin = this;
|
||||
tempStruct->word = selectedWord;
|
||||
tempStruct->wordPositionEnd = wordStart + wordLen;
|
||||
tempStruct->wordPositionStart = wordStart;
|
||||
tempStruct->wordY = y;
|
||||
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
|
||||
"Add Word", spell_add, NULL, tempStruct);
|
||||
tempStruct->menuItem = suggMenuItem;
|
||||
suggestionMenuItems.push_back(tempStruct);
|
||||
menu->addChild(suggMenuItem);
|
||||
menu->addChild(new LLMenuItemCallGL("Add Word", spell_add, nullptr, this));
|
||||
}
|
||||
}
|
||||
|
||||
SpellMenuBind * tempStruct = new SpellMenuBind;
|
||||
tempStruct->origin = this;
|
||||
if (glggHunSpell->getSpellCheckHighlight())
|
||||
{
|
||||
tempStruct->word = "Hide Misspellings";
|
||||
}
|
||||
else
|
||||
{
|
||||
tempStruct->word = "Show Misspellings";
|
||||
}
|
||||
|
||||
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
|
||||
tempStruct->word, spell_show, NULL, tempStruct);
|
||||
tempStruct->menuItem = suggMenuItem;
|
||||
suggestionMenuItems.push_back(tempStruct);
|
||||
menu->addChild(suggMenuItem);
|
||||
bool show = !glggHunSpell->getSpellCheckHighlight();
|
||||
auto word = show ? "Show Misspellings" : "Hide Misspellings";
|
||||
menu->addChild(new LLMenuItemCallGL(word, spell_show, nullptr, show ? &show : nullptr));
|
||||
}
|
||||
|
||||
mLastContextMenuX = x;
|
||||
mLastContextMenuY = y;
|
||||
menu->buildDrawLabels();
|
||||
menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, menu, x, y);
|
||||
showMenu(this, menu, x, y);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2356,7 +2217,7 @@ BOOL LLTextEditor::canCopy() const
|
||||
}
|
||||
|
||||
// copy selection to clipboard
|
||||
void LLTextEditor::copy(bool raw)
|
||||
void LLTextEditor::copy(bool raw) const
|
||||
{
|
||||
if( !canCopy() )
|
||||
{
|
||||
@@ -2420,17 +2281,6 @@ BOOL LLTextEditor::canPaste() const
|
||||
}
|
||||
|
||||
|
||||
void LLTextEditor::spellReplace(SpellMenuBind* spellData)
|
||||
{
|
||||
remove( spellData->wordPositionStart,
|
||||
spellData->wordPositionEnd - spellData->wordPositionStart, TRUE );
|
||||
LLWString clean_string = utf8str_to_wstring(spellData->word);
|
||||
insert(spellData->wordPositionStart, clean_string, FALSE);
|
||||
mCursorPos+=clean_string.length() - (spellData->wordPositionEnd-spellData->wordPositionStart);
|
||||
needsReflow();
|
||||
}
|
||||
|
||||
|
||||
// paste from clipboard
|
||||
void LLTextEditor::paste()
|
||||
{
|
||||
@@ -4352,7 +4202,7 @@ void LLTextEditor::appendTextImpl(const std::string &new_text, const LLStyleSP s
|
||||
if (mReadOnly && mParseHTML && !is_link) // Singu Note: Do not replace html if the user is going to edit it. (Like in profiles)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_PARSE_HTML);
|
||||
S32 start=0,end=0;
|
||||
size_t start=0, end=0;
|
||||
LLUrlMatch match;
|
||||
auto append_substr = [&](const size_t& pos, const size_t& count)
|
||||
{
|
||||
@@ -4360,6 +4210,12 @@ void LLTextEditor::appendTextImpl(const std::string &new_text, const LLStyleSP s
|
||||
};
|
||||
auto append_link = [&](const std::string& link, LLStyleSP link_style)
|
||||
{
|
||||
if (!link_style->isLink())
|
||||
{
|
||||
appendAndHighlightText(link, part, style);
|
||||
return;
|
||||
}
|
||||
|
||||
if (style) // Respect styling
|
||||
{
|
||||
const auto& text_style = *style;
|
||||
@@ -4373,8 +4229,9 @@ void LLTextEditor::appendTextImpl(const std::string &new_text, const LLStyleSP s
|
||||
if (always_underline) link_style->mUnderline = true;
|
||||
appendAndHighlightText(link, part, link_style, !always_underline/*match.underlineOnHoverOnly()*/);
|
||||
};
|
||||
const auto&& cb = force_replace_links ? boost::bind(&LLTextEditor::replaceUrl, this, _1, _2, _3) : LLUrlLabelCallback();
|
||||
while (!text.empty() && LLUrlRegistry::instance().findUrl(text, match, cb))
|
||||
const auto&& cb = force_replace_links ? boost::bind(&LLTextEditor::replaceUrl, this, _1, _2, _3) : static_cast<LLUrlLabelCallback>(LLUrlRegistryNullCallback);
|
||||
auto& urlr = LLUrlRegistry::instance();
|
||||
while (!text.empty() && urlr.findUrl(text, match, cb))
|
||||
{
|
||||
start = match.getStart();
|
||||
end = match.getEnd()+1;
|
||||
@@ -4497,7 +4354,7 @@ void LLTextEditor::appendAndHighlightText(const std::string& new_text, S32 highl
|
||||
std::string::size_type start = 0;
|
||||
/*std::string::size_type pos = new_text.find('\n',start);
|
||||
|
||||
while(pos!=-1)
|
||||
while(pos != std::string::npos)
|
||||
{
|
||||
if(pos!=start)
|
||||
{
|
||||
@@ -5238,24 +5095,6 @@ BOOL LLTextEditor::exportBuffer(std::string &buffer )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boost::signals2::connection LLTextEditor::setIsFriendCallback(const is_friend_signal_t::slot_type& cb)
|
||||
{
|
||||
if (!mIsFriendSignal)
|
||||
{
|
||||
mIsFriendSignal = new is_friend_signal_t();
|
||||
}
|
||||
return mIsFriendSignal->connect(cb);
|
||||
}
|
||||
|
||||
boost::signals2::connection LLTextEditor::setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb)
|
||||
{
|
||||
if (!mIsObjectBlockedSignal)
|
||||
{
|
||||
mIsObjectBlockedSignal = new is_blocked_signal_t();
|
||||
}
|
||||
return mIsObjectBlockedSignal->connect(cb);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// LLTextSegment
|
||||
|
||||
|
||||
@@ -43,16 +43,15 @@
|
||||
#include "lleditmenuhandler.h"
|
||||
|
||||
#include "llpreeditor.h"
|
||||
#include "llmenugl.h"
|
||||
#include "lfidbearer.h"
|
||||
|
||||
class LLFontGL;
|
||||
class LLScrollbar;
|
||||
class LLViewBorder;
|
||||
class LLKeywordToken;
|
||||
class LLMenuGL;
|
||||
class LLTextCmd;
|
||||
class LLUICtrlFactory;
|
||||
|
||||
class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
|
||||
, public LFIDBearer
|
||||
{
|
||||
public:
|
||||
//
|
||||
@@ -74,16 +73,12 @@ public:
|
||||
|
||||
const std::string& getMenuSegmentUrl() const;
|
||||
|
||||
LLUUID getStringUUIDSelectedItem() const override final;
|
||||
Type getSelectedType() const override final;
|
||||
|
||||
typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
|
||||
typedef boost::signals2::signal<bool(const LLUUID& user_id)> is_friend_signal_t;
|
||||
typedef boost::signals2::signal<bool(const LLUUID& blocked_id, const std::string from)> is_blocked_signal_t;
|
||||
|
||||
static boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb);
|
||||
static boost::signals2::connection setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb);
|
||||
|
||||
typedef std::function<void(const std::string&, const LLUUID&)> ext_slurl_cb;
|
||||
typedef std::function<bool(const std::string&, const LLUUID&)> ext_slurl_visible_cb;
|
||||
static void addMenuListeners(ext_slurl_cb cb, ext_slurl_visible_cb vcb);
|
||||
static void addMenuListeners();
|
||||
|
||||
void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
|
||||
|
||||
@@ -126,16 +121,6 @@ public:
|
||||
virtual BOOL isDirty() const { return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); }
|
||||
BOOL isSpellDirty() const { return mWText != mPrevSpelledText; } // Returns TRUE if user changed value at all
|
||||
void resetSpellDirty() { mPrevSpelledText = mWText; } // Clear dirty state
|
||||
|
||||
struct SpellMenuBind
|
||||
{
|
||||
LLTextEditor* origin;
|
||||
LLMenuItemCallGL * menuItem;
|
||||
std::string word;
|
||||
S32 wordPositionStart;
|
||||
S32 wordPositionEnd;
|
||||
S32 wordY;
|
||||
};
|
||||
|
||||
// LLEditMenuHandler interface
|
||||
virtual void undo();
|
||||
@@ -144,15 +129,13 @@ public:
|
||||
virtual BOOL canRedo() const;
|
||||
virtual void cut();
|
||||
virtual BOOL canCut() const;
|
||||
void copy(bool raw);
|
||||
void copyRaw() { copy(true); }
|
||||
virtual void copy() { copy(false); }
|
||||
void copy(bool raw) const;
|
||||
void copyRaw() const { copy(true); }
|
||||
void copy() const override final { copy(false); }
|
||||
virtual BOOL canCopy() const;
|
||||
virtual void paste();
|
||||
virtual BOOL canPaste() const;
|
||||
|
||||
virtual void spellReplace(SpellMenuBind* spellData);
|
||||
|
||||
virtual void updatePrimary();
|
||||
virtual void copyPrimary();
|
||||
virtual void pastePrimary();
|
||||
@@ -483,10 +466,6 @@ protected:
|
||||
void (*mOnScrollEndCallback)(void*);
|
||||
void *mOnScrollEndData;
|
||||
|
||||
// Used to check if user with given ID is avatar's friend
|
||||
static is_friend_signal_t* mIsFriendSignal;
|
||||
static is_blocked_signal_t* mIsObjectBlockedSignal;
|
||||
|
||||
LLWString mPreeditWString;
|
||||
LLWString mPreeditOverwrittenWString;
|
||||
std::vector<S32> mPreeditPositions;
|
||||
@@ -580,7 +559,6 @@ private:
|
||||
typedef std::vector<line_info> line_list_t;
|
||||
|
||||
//to keep track of what we have to remove before showing menu
|
||||
std::vector<SpellMenuBind* > suggestionMenuItems;
|
||||
S32 mLastContextMenuX;
|
||||
S32 mLastContextMenuY;
|
||||
|
||||
|
||||
@@ -406,16 +406,16 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const std::string &filename, LLView* parent
|
||||
LLXMLNodePtr root;
|
||||
LLMenuGL* menu;
|
||||
|
||||
if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
|
||||
if (!getLayeredXMLNode(filename, root))
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// root must be called panel
|
||||
if( !root->hasName( "menu_bar" ) && !root->hasName( "menu" ) && !root->hasName("context_menu"))
|
||||
if (!root->hasName("menu_bar") && !root->hasName("menu") && !root->hasName("context_menu"))
|
||||
{
|
||||
LL_WARNS() << "Root node should be named menu bar or menu in : " << filename << LL_ENDL;
|
||||
return NULL;
|
||||
LL_WARNS() << "Root node should be named menu bar or menu in: " << filename << LL_ENDL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (root->hasName("menu") || root->hasName("context_menu"))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user