Merge branch 'master' of https://vcs.firestormviewer.org/phoenix-firestorm
# Conflicts: # indra/llcommon/llsdserialize.cpp # indra/llcommon/llsdserialize.h # indra/llmath/llvolume.cpp # indra/llrender/llgl.cpp # indra/llxml/llcontrol.cpp # indra/newview/llpanelnearbymedia.cpp # indra/newview/llsceneview.cpp # indra/newview/llselectmgr.cpp # indra/newview/llstartup.cpp # indra/newview/lltextureview.cpp # indra/newview/llvovolume.cpp # indra/newview/skins/default/xui/en/menu_viewer.xmlmaster
commit
701cf51cd7
|
|
@ -30,6 +30,7 @@ indra/tools/vstool/* -text
|
|||
# Files with Windows line endings
|
||||
VivoxAUP.txt text eol=crlf
|
||||
FILES_ARE_UNICODE_UTF-16LE.txt text eol=crlf
|
||||
*.nsi text eol=crlf
|
||||
|
||||
# Windows Manifest files
|
||||
*.manifest text eol=crlf
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
name: Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [main, contribute]
|
||||
tags: ["*"]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
runner: [windows-large]
|
||||
configuration: [ReleaseOS]
|
||||
addrsize: [64]
|
||||
include:
|
||||
- runner: windows-large
|
||||
configuration: ReleaseOS
|
||||
addrsize: 32
|
||||
runs-on: ${{ matrix.runner }}
|
||||
env:
|
||||
AUTOBUILD_CONFIGURATION: ${{ matrix.configuration }}
|
||||
AUTOBUILD_ADDRSIZE: ${{ matrix.addrsize }}
|
||||
AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables
|
||||
AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables
|
||||
AUTOBUILD_VSVER: "170" # vs2k22
|
||||
LOGFAIL: debug # Show details when tests fail
|
||||
GIT_REF: ${{ github.head_ref || github.ref }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Checkout build variables
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: secondlife/build-variables
|
||||
ref: viewer
|
||||
path: .build-variables
|
||||
|
||||
- name: Install autobuild and python dependencies
|
||||
run: pip3 install autobuild llbase
|
||||
|
||||
- name: Cache autobuild packages
|
||||
uses: actions/cache@v3
|
||||
id: cache-installables
|
||||
with:
|
||||
path: .autobuild-installables
|
||||
key: ${{ runner.os }}-${{ matrix.addrsize }}-${{ matrix.configuration }}-${{ hashFiles('autobuild.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.addrsize }}-${{ matrix.configuration }}-
|
||||
${{ runner.os }}-${{ matrix.addrsize }}-
|
||||
|
||||
- name: Install windows dependencies
|
||||
if: runner.os == 'Windows'
|
||||
run: choco install nsis-unicode
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
shell: bash
|
||||
env:
|
||||
RUNNER_OS: ${{ runner.os }}
|
||||
run: |
|
||||
# On windows we need to point the build to the correct python
|
||||
# as neither CMake's FindPython nor our custom Python.cmake module
|
||||
# will resolve the correct interpreter location.
|
||||
if [[ "$RUNNER_OS" == "Windows" ]]; then
|
||||
export PYTHON="$(cygpath -m "$(which python)")"
|
||||
echo "Python location: $PYTHON"
|
||||
fi
|
||||
|
||||
autobuild configure -- -DVIEWER_CHANNEL="Second Life Test ${GIT_REF##*/}"
|
||||
autobuild build --no-configure
|
||||
|
||||
# Find artifacts
|
||||
if [[ "$RUNNER_OS" == "Windows" ]]; then
|
||||
installer_path=$(find ./build-*/newview/ | grep '_Setup\.exe')
|
||||
installer_name="$(basename $installer_path)"
|
||||
elif [[ "$RUNNER_OS" == "macOS" ]]; then
|
||||
installer_path=$(find ./build-*/newview/ | grep '\.dmg')
|
||||
installer_name="$(basename $installer_path)"
|
||||
fi
|
||||
|
||||
echo "installer_path=$installer_path" >> $GITHUB_OUTPUT
|
||||
echo "installer_name=$installer_name" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload installer
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.build.outputs.installer_name }}
|
||||
path: ${{ steps.build.outputs.installer_path }}
|
||||
|
|
@ -2,8 +2,9 @@ name: Build viewer
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- "*release"
|
||||
- master
|
||||
- "Firestorm*.*.*"
|
||||
tags:
|
||||
- "preview"
|
||||
schedule:
|
||||
- cron: '00 03 * * *' # Run every day at 3am UTC
|
||||
env:
|
||||
|
|
@ -74,14 +75,14 @@ jobs:
|
|||
|
||||
- name: find channel from Branch name
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" == *Release* ]]; then
|
||||
if [[ "${{ github.ref_name }}" == Firestorm* ]]; then
|
||||
FS_RELEASE_TYPE=Release
|
||||
elif [[ "${{ github.ref_name }}" == *review* ]]; then
|
||||
FS_RELEASE_TYPE=Beta
|
||||
elif [[ "${{ github.event_name }}" == 'schedule' ]]; then
|
||||
FS_RELEASE_TYPE=Nightly
|
||||
else
|
||||
if [[ "${{github.event_name}}" == 'schedule' ]]; then
|
||||
FS_RELEASE_TYPE=Nightly
|
||||
else
|
||||
FS_RELEASE_TYPE=Beta
|
||||
fi
|
||||
FS_RELEASE_TYPE=Unknown
|
||||
fi
|
||||
if [[ "${{ matrix.addrsize }}" == "64" ]]; then
|
||||
FS_RELEASE_CHAN="${FS_RELEASE_TYPE}x64"
|
||||
|
|
@ -118,7 +119,11 @@ jobs:
|
|||
shell: bash
|
||||
|
||||
- name: rclone the private 3p packages for this platform (both 64 & 32)
|
||||
run: 'rclone copy fs_bundles: --include "*${{ env.fallback_platform }}*bz2" .'
|
||||
run: 'rclone copy fs_bundles: --filter "- Alpha/*" --filter "+ *${{ env.fallback_platform }}*bz2" .'
|
||||
|
||||
- name: rclone any extra private 3p packages for Alpha (allows library updates not in the main repo)
|
||||
if: env.FS_BUILD_TYPE == 'Alpha'
|
||||
run: 'rclone copy fs_bundles:Alpha --include "*${{ env.fallback_platform }}*bz2" .'
|
||||
|
||||
- name: set VSVER for Windows builds
|
||||
if: runner.os == 'Windows'
|
||||
|
|
@ -255,17 +260,17 @@ jobs:
|
|||
|
||||
- name: find channel and webhook from Branch name
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" == *Release* ]]; then
|
||||
if [[ "${{ github.ref_name }}" == Firestorm* ]]; then
|
||||
FS_RELEASE_FOLDER=release
|
||||
FS_BUILD_WEBHOOK_URL=${{ secrets.RELEASE_WEBHOOK_URL }}
|
||||
else
|
||||
if [[ "${{github.event_name}}" == 'schedule' ]]; then
|
||||
FS_RELEASE_FOLDER=nightly
|
||||
FS_BUILD_WEBHOOK_URL=${{ secrets.NIGHTLY_WEBHOOK_URL }}
|
||||
else
|
||||
elif [[ "${{ github.ref_name }}" == *review* ]]; then
|
||||
FS_RELEASE_FOLDER=preview
|
||||
FS_BUILD_WEBHOOK_URL=${{ secrets.BETA_WEBHOOK_URL }}
|
||||
fi
|
||||
elif [[ "${{ github.event_name }}" == 'schedule' ]]; then
|
||||
FS_RELEASE_FOLDER=nightly
|
||||
FS_BUILD_WEBHOOK_URL=${{ secrets.NIGHTLY_WEBHOOK_URL }}
|
||||
else
|
||||
FS_RELEASE_TYPE=Unknown
|
||||
fi
|
||||
echo "FS_RELEASE_FOLDER=${FS_RELEASE_FOLDER}" >> $GITHUB_ENV
|
||||
echo "FS_BUILD_WEBHOOK_URL=${FS_BUILD_WEBHOOK_URL}" >> $GITHUB_ENV
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
name: pre-commit
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [main, contribute]
|
||||
tags: [v*]
|
||||
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
- uses: pre-commit/action@v3.0.0
|
||||
|
|
@ -15,8 +15,8 @@ jobs:
|
|||
- uses: actions/stale@v6
|
||||
id: stale
|
||||
with:
|
||||
stale-pr-message: This pull request is stale because it has been open 60 days with no activity. Remove stale label or comment or it will be closed in 7 days
|
||||
days-before-stale: 60
|
||||
stale-pr-message: This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or it will be closed in 7 days
|
||||
days-before-stale: 30
|
||||
days-before-close: 7
|
||||
exempt-pr-labels: blocked,must,should,keep
|
||||
stale-pr-label: stale
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
repos:
|
||||
- repo: https://bitbucket.org/lindenlab/git-hooks.git
|
||||
rev: v1.0.0-beta2
|
||||
- repo: https://github.com/secondlife/git-hooks.git
|
||||
rev: v1.0.0
|
||||
hooks:
|
||||
- id: opensource-license
|
||||
- id: jira-issue
|
||||
- id: llsd
|
||||
- id: no-trigraphs
|
||||
- id: copyright
|
||||
|
|
@ -11,7 +10,7 @@ repos:
|
|||
files: \.(cpp|c|h|py|glsl|cmake|txt)$
|
||||
exclude: language.txt
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.5.0
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-xml
|
||||
- id: mixed-line-ending
|
||||
|
|
|
|||
|
|
@ -3430,9 +3430,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9e1b5515ab59b4e9cfeef6626d65d03d</string>
|
||||
<string>6ba629ff34c4b14a1f851de707bc35041df8b6a9</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108609/945996/viewer_manager-3.0.577252-darwin64-577252.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-bd3aec2/viewer_manager-3.0-bd3aec2-darwin64-bd3aec2.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3442,24 +3444,28 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>129b80dd47b53bfa02fc21ab1eb1901c</string>
|
||||
<string>7e086a28db17b0c086a5460e9d62f0c6584560b3</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>http://3p.firestormviewer.org/viewer_manager-1.0.180861311-linux64-180861311.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-bd3aec2/viewer_manager-3.0-bd3aec2-linux64-bd3aec2.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>a3c599595ecc8fb987a5499fca42520a</string>
|
||||
<string>1eab994c0c1df5b2c057878a4071a88320cec978</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108610/946003/viewer_manager-3.0.577252-windows-577252.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-bd3aec2/viewer_manager-3.0-bd3aec2-windows64-bd3aec2.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>source</key>
|
||||
|
|
@ -3467,7 +3473,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>source_type</key>
|
||||
<string>hg</string>
|
||||
<key>version</key>
|
||||
<string>3.0.577252</string>
|
||||
<string>3.0-bd3aec2</string>
|
||||
</map>
|
||||
<key>vlc-bin</key>
|
||||
<map>
|
||||
|
|
@ -4404,7 +4410,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<string>/t:Build</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:minimal</string>
|
||||
<string>/toolsversion:4.0</string>
|
||||
<string>/p:VCBuildAdditionalOptions= /incremental</string>
|
||||
</array>
|
||||
</map>
|
||||
|
|
@ -4478,7 +4483,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<string>/t:Build</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:minimal</string>
|
||||
<string>/toolsversion:4.0</string>
|
||||
<string>/p:VCBuildAdditionalOptions= /incremental</string>
|
||||
</array>
|
||||
</map>
|
||||
|
|
|
|||
|
|
@ -600,6 +600,7 @@ Henri Beauchamp
|
|||
VWR-4157
|
||||
SL-15175
|
||||
SL-19110
|
||||
SL-19159
|
||||
herina Bode
|
||||
Hikkoshi Sakai
|
||||
VWR-429
|
||||
|
|
@ -940,6 +941,8 @@ Lexi Frua
|
|||
Lillie Cordeaux
|
||||
Lilly Zenovka
|
||||
Lizzy Macarthur
|
||||
Logue Takacs
|
||||
INTL-490
|
||||
Luban Yiyuan
|
||||
Luc Starsider
|
||||
Luminous Luminos
|
||||
|
|
@ -1196,6 +1199,7 @@ PanteraPolnocy
|
|||
SL-18891
|
||||
SL-18904
|
||||
SL-18937
|
||||
SL-19207
|
||||
SL-19681
|
||||
Parvati Silverweb
|
||||
Patric Mills
|
||||
|
|
|
|||
|
|
@ -77,11 +77,9 @@ if (WINDOWS)
|
|||
# CP changed to only append the flag for 32bit builds - on 64bit builds,
|
||||
# locally at least, the build output is spammed with 1000s of 'D9002'
|
||||
# warnings about this switch being ignored.
|
||||
# <FS:ND> Remove this, it's no option to cl.exe and causes a massive amount of warnings.
|
||||
#if( ADDRESS_SIZE EQUAL 32 )
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")
|
||||
#endif()
|
||||
|
||||
if(ADDRESS_SIZE EQUAL 32 AND DEFINED ENV{"TEAMCITY_PROJECT_NAME"})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")
|
||||
endif()
|
||||
# zlib has assembly-language object files incompatible with SAFESEH
|
||||
add_link_options(/LARGEADDRESSAWARE
|
||||
/SAFESEH:NO
|
||||
|
|
@ -216,6 +214,10 @@ if (DARWIN)
|
|||
|
||||
set(ENABLE_SIGNING TRUE)
|
||||
set(SIGNING_IDENTITY "Developer ID Application: The Phoenix Firestorm Project, Inc." )
|
||||
|
||||
# required for clang-15/xcode-15 since our boost package still uses deprecated std::unary_function/binary_function
|
||||
# see https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#C++-Standard-Library
|
||||
add_compile_definitions(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION)
|
||||
endif (DARWIN)
|
||||
|
||||
if (LINUX OR DARWIN)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
set(PYTHONINTERP_FOUND)
|
||||
|
||||
if (WINDOWS)
|
||||
if (DEFINED ENV{PYTHON})
|
||||
# Allow python executable to be explicitly set
|
||||
set(python "$ENV{PYTHON}")
|
||||
set(PYTHONINTERP_FOUND ON)
|
||||
elseif (WINDOWS)
|
||||
# On Windows, explicitly avoid Cygwin Python.
|
||||
|
||||
if (DEFINED ENV{VIRTUAL_ENV})
|
||||
|
|
@ -53,7 +57,7 @@ else()
|
|||
if (python)
|
||||
set(PYTHONINTERP_FOUND ON)
|
||||
endif (python)
|
||||
endif (WINDOWS)
|
||||
endif (DEFINED ENV{PYTHON})
|
||||
|
||||
if (NOT python)
|
||||
message(FATAL_ERROR "No Python interpreter found")
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#include "llsaleinfo.h"
|
||||
#include "llwearabletype.h"
|
||||
|
||||
class LLMD5;
|
||||
class LLMD5; // <FS:Ansariel> [Legacy Bake]
|
||||
class LLVisualParam;
|
||||
class LLTexGlobalColorInfo;
|
||||
class LLTexGlobalColor;
|
||||
|
|
@ -131,6 +131,7 @@ public:
|
|||
// Something happened that requires the wearable to be updated (e.g. worn/unworn).
|
||||
virtual void setUpdated() const = 0;
|
||||
|
||||
// <FS:Ansariel> [Legacy Bake]
|
||||
// Update the baked texture hash.
|
||||
virtual void addToBakedTextureHash(LLMD5& hash) const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "llavatarappearance.h"
|
||||
#include "llavatarappearancedefines.h"
|
||||
#include "lldriverparam.h"
|
||||
#include "llmd5.h"
|
||||
#include "llmd5.h" // <FS:Ansariel> [Legacy Bake]
|
||||
|
||||
LLWearableData::LLWearableData() :
|
||||
mAvatarAppearance(NULL)
|
||||
|
|
@ -355,6 +355,7 @@ U32 LLWearableData::getWearableCount(const U32 tex_index) const
|
|||
return getWearableCount(wearable_type);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> [Legacy Bake]
|
||||
LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
|
||||
BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
|
||||
{
|
||||
|
|
@ -391,5 +392,6 @@ LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBaked
|
|||
|
||||
return hash_id;
|
||||
}
|
||||
// </FS:Ansariel> [Legacy Bake]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ protected:
|
|||
private:
|
||||
void pullCrossWearableValues(const LLWearableType::EType type);
|
||||
|
||||
// <FS:Ansariel> [Legacy Bake]
|
||||
//--------------------------------------------------------------------
|
||||
// Server Communication
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -93,6 +94,7 @@ public:
|
|||
BOOL generate_valid_hash = TRUE);
|
||||
protected:
|
||||
virtual void invalidateBakedTextureHash(LLMD5& hash) const {}
|
||||
// </FS:Ansariel> [Legacy Bake]
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Member variables
|
||||
|
|
|
|||
|
|
@ -217,7 +217,8 @@ std::string LLAudioEngine::getInternetStreamURL()
|
|||
{
|
||||
if (mStreamingAudioImpl)
|
||||
return mStreamingAudioImpl->getURL();
|
||||
else return std::string();
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -358,42 +359,43 @@ void LLAudioEngine::idle()
|
|||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
||||
// Check to see if the current sound is done playing.
|
||||
if (!channelp->isPlaying())
|
||||
{
|
||||
// Check to see if the current sound is done playing, or looped.
|
||||
if (!channelp->isPlaying())
|
||||
sourcep->mCurrentDatap = sourcep->mQueuedDatap;
|
||||
sourcep->mQueuedDatap = NULL;
|
||||
|
||||
// Reset the timer so the source doesn't die.
|
||||
sourcep->mAgeTimer.reset();
|
||||
|
||||
// Make sure we have the buffer set up if we just decoded the data
|
||||
if (sourcep->mCurrentDatap)
|
||||
{
|
||||
updateBufferForData(sourcep->mCurrentDatap);
|
||||
}
|
||||
|
||||
// Actually play the associated data.
|
||||
sourcep->setupChannel();
|
||||
channelp->updateBuffer();
|
||||
sourcep->getChannel()->play();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check to see if the current sound is looped.
|
||||
if (sourcep->isLoop())
|
||||
{
|
||||
// It's a loop, we need to check and see if we're done with it.
|
||||
if (channelp->mLoopedThisFrame)
|
||||
{
|
||||
sourcep->mCurrentDatap = sourcep->mQueuedDatap;
|
||||
sourcep->mQueuedDatap = NULL;
|
||||
|
||||
// Reset the timer so the source doesn't die.
|
||||
sourcep->mAgeTimer.reset();
|
||||
|
||||
// Make sure we have the buffer set up if we just decoded the data
|
||||
if (sourcep->mCurrentDatap)
|
||||
{
|
||||
updateBufferForData(sourcep->mCurrentDatap);
|
||||
}
|
||||
|
||||
// Actually play the associated data.
|
||||
// Actually, should do a time sync so if we're a loop master/slave
|
||||
// we don't drift away.
|
||||
sourcep->setupChannel();
|
||||
channelp->updateBuffer();
|
||||
sourcep->getChannel()->play();
|
||||
}
|
||||
else if (sourcep->isLoop())
|
||||
{
|
||||
// It's a loop, we need to check and see if we're done with it.
|
||||
if (channelp->mLoopedThisFrame)
|
||||
{
|
||||
sourcep->mCurrentDatap = sourcep->mQueuedDatap;
|
||||
sourcep->mQueuedDatap = NULL;
|
||||
|
||||
// Actually, should do a time sync so if we're a loop master/slave
|
||||
// we don't drift away.
|
||||
sourcep->setupChannel();
|
||||
sourcep->getChannel()->play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -409,18 +411,11 @@ void LLAudioEngine::idle()
|
|||
for (source_map::value_type& src_pair : mAllSources)
|
||||
{
|
||||
LLAudioSource *sourcep = src_pair.second;
|
||||
if (sourcep->isMuted())
|
||||
if (sourcep->isMuted() && sourcep->isSyncMaster() && sourcep->getPriority() > max_sm_priority)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (sourcep->isSyncMaster())
|
||||
{
|
||||
if (sourcep->getPriority() > max_sm_priority)
|
||||
{
|
||||
sync_masterp = sourcep;
|
||||
master_channelp = sync_masterp->getChannel();
|
||||
max_sm_priority = sourcep->getPriority();
|
||||
}
|
||||
sync_masterp = sourcep;
|
||||
master_channelp = sync_masterp->getChannel();
|
||||
max_sm_priority = sourcep->getPriority();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -755,7 +750,7 @@ F64 LLAudioEngine::mapWindVecToGain(LLVector3 wind_vec)
|
|||
}
|
||||
|
||||
return (gain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
F64 LLAudioEngine::mapWindVecToPitch(LLVector3 wind_vec)
|
||||
|
|
@ -996,11 +991,10 @@ void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp)
|
|||
else
|
||||
{
|
||||
LL_DEBUGS("AudioEngine") << "Cleaning up audio sources for "<< asp->getID() <<LL_ENDL;
|
||||
delete asp;
|
||||
mAllSources.erase(iter);
|
||||
delete asp;
|
||||
mAllSources.erase(iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
|
||||
{
|
||||
|
|
@ -1829,19 +1823,18 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep)
|
|||
{
|
||||
LL_DEBUGS("AudioEngine") << "( id: " << sourcep->getID() << ")" << LL_ENDL;
|
||||
|
||||
if (sourcep == mCurrentSourcep)
|
||||
{
|
||||
// Don't reallocate the channel, this will make FMOD goofy.
|
||||
//LL_INFOS() << "Calling setSource with same source!" << LL_ENDL;
|
||||
if (sourcep == mCurrentSourcep)
|
||||
{
|
||||
// Don't reallocate the channel, this will make FMOD goofy.
|
||||
//LL_INFOS() << "Calling setSource with same source!" << LL_ENDL;
|
||||
}
|
||||
|
||||
mCurrentSourcep = sourcep;
|
||||
|
||||
updateBuffer();
|
||||
update3DPosition();
|
||||
}
|
||||
|
||||
mCurrentSourcep = sourcep;
|
||||
|
||||
updateBuffer();
|
||||
update3DPosition();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLAudioChannel::updateBuffer()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ public:
|
|||
// initialization/startup/shutdown
|
||||
virtual bool init(void *userdata, const std::string &app_title);
|
||||
virtual std::string getDriverName(bool verbose) = 0;
|
||||
virtual LLStreamingAudioInterface *createDefaultStreamingAudioImpl() const = 0;
|
||||
virtual void shutdown();
|
||||
|
||||
// Used by the mechanics of the engine
|
||||
|
|
@ -526,13 +527,13 @@ struct SoundData
|
|||
const LLUUID& owner_id,
|
||||
const F32 gain,
|
||||
const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
|
||||
const LLVector3d &pos_global = LLVector3d::zero)
|
||||
const LLVector3d &pos_global = LLVector3d::zero) :
|
||||
audio_uuid(audio_uuid),
|
||||
owner_id(owner_id),
|
||||
gain(gain),
|
||||
type(type),
|
||||
pos_global(pos_global)
|
||||
{
|
||||
this->audio_uuid = audio_uuid;
|
||||
this->owner_id = owner_id;
|
||||
this->gain = gain;
|
||||
this->type = type;
|
||||
this->pos_global = pos_global;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -308,10 +308,6 @@ bool LLAudioEngine_FMODSTUDIO::init(void* userdata, const std::string &app_title
|
|||
Check_FMOD_Error(mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]), "FMOD::System::createChannelGroup");
|
||||
}
|
||||
|
||||
// set up our favourite FMOD-native streaming audio implementation if none has already been added
|
||||
if (!getStreamingAudioImpl()) // no existing implementation added
|
||||
setStreamingAudioImpl(new LLStreamingAudio_FMODSTUDIO(mSystem));
|
||||
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() FMOD Studio initialized correctly" << LL_ENDL;
|
||||
|
||||
FMOD_ADVANCEDSETTINGS settings_dump = { };
|
||||
|
|
@ -395,6 +391,13 @@ std::string LLAudioEngine_FMODSTUDIO::getDriverName(bool verbose)
|
|||
}
|
||||
|
||||
|
||||
// create our favourite FMOD-native streaming audio implementation
|
||||
LLStreamingAudioInterface *LLAudioEngine_FMODSTUDIO::createDefaultStreamingAudioImpl() const
|
||||
{
|
||||
return new LLStreamingAudio_FMODSTUDIO(mSystem);
|
||||
}
|
||||
|
||||
|
||||
void LLAudioEngine_FMODSTUDIO::allocateListener(void)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public:
|
|||
// initialization/startup/shutdown
|
||||
virtual bool init(void *user_data, const std::string &app_title);
|
||||
virtual std::string getDriverName(bool verbose);
|
||||
virtual LLStreamingAudioInterface* createDefaultStreamingAudioImpl() const;
|
||||
virtual void allocateListener();
|
||||
|
||||
virtual void shutdown();
|
||||
|
|
|
|||
|
|
@ -500,13 +500,20 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
|
|||
// request asset
|
||||
mAssetStatus = ASSET_FETCHED;
|
||||
|
||||
LL_DEBUGS("Animation") << "Requesting data fetch for: " << mID << LL_ENDL;
|
||||
character_id = new LLUUID(mCharacter->getID());
|
||||
gAssetStorage->getAssetData(mID,
|
||||
LLAssetType::AT_ANIMATION,
|
||||
onLoadComplete,
|
||||
(void *)character_id,
|
||||
FALSE);
|
||||
if (mID.notNull())
|
||||
{
|
||||
LL_DEBUGS("Animation") << "Requesting data fetch for: " << mID << LL_ENDL;
|
||||
character_id = new LLUUID(mCharacter->getID());
|
||||
gAssetStorage->getAssetData(mID,
|
||||
LLAssetType::AT_ANIMATION,
|
||||
onLoadComplete,
|
||||
(void*)character_id,
|
||||
FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS("Animation") << "Attempted to fetch animation " << mName << " with null id for character " << mCharacter->getID() << LL_ENDL;
|
||||
}
|
||||
|
||||
return STATUS_HOLD;
|
||||
case ASSET_FETCHED:
|
||||
|
|
|
|||
|
|
@ -96,6 +96,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// Make this class no-copy (it would be possible, with custom copy
|
||||
// operators, but it is not trivially copyable, because of the mState
|
||||
// pointer): it does not really make sense to allow copying it anyway,
|
||||
// since all we care about is the resulting digest (so you should only
|
||||
// need and care about storing/copying the digest and not a class
|
||||
// instance).
|
||||
HBXXH64(const HBXXH64&) noexcept = delete;
|
||||
HBXXH64& operator=(const HBXXH64&) noexcept = delete;
|
||||
|
||||
~HBXXH64();
|
||||
|
||||
void update(const void* buffer, size_t len);
|
||||
|
|
@ -199,6 +208,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// Make this class no-copy (it would be possible, with custom copy
|
||||
// operators, but it is not trivially copyable, because of the mState
|
||||
// pointer): it does not really make sense to allow copying it anyway,
|
||||
// since all we care about is the resulting digest (so you should only
|
||||
// need and care about storing/copying the digest and not a class
|
||||
// instance).
|
||||
HBXXH128(const HBXXH128&) noexcept = delete;
|
||||
HBXXH128& operator=(const HBXXH128&) noexcept = delete;
|
||||
|
||||
~HBXXH128();
|
||||
|
||||
void update(const void* buffer, size_t len);
|
||||
|
|
|
|||
|
|
@ -349,6 +349,7 @@ const U8 CLICK_ACTION_PLAY = 5;
|
|||
const U8 CLICK_ACTION_OPEN_MEDIA = 6;
|
||||
const U8 CLICK_ACTION_ZOOM = 7;
|
||||
const U8 CLICK_ACTION_DISABLED = 8;
|
||||
const U8 CLICK_ACTION_IGNORE = 9;
|
||||
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -828,11 +828,11 @@ bool unix_post_minidump_callback(const char *dump_dir,
|
|||
auto dirPathLength = strlen(dump_dir);
|
||||
auto idLength = strlen(minidump_id);
|
||||
|
||||
// The path must not be truncated.
|
||||
llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
|
||||
// The path must not be truncated, and we need to have room left for a terminating zero.
|
||||
llassert((dirPathLength + idLength + 5) < LLApp::MAX_MINDUMP_PATH_LENGTH); // <FS:Beq/> Buffer overrun avoidance (from Aleric Inglewood)
|
||||
|
||||
char * path = LLApp::instance()->getMiniDumpFilename();
|
||||
auto remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
|
||||
auto remaining = LLApp::MAX_MINDUMP_PATH_LENGTH - 1; // <FS:Beq/> Buffer overrun avoidance (from Aleric Inglewood
|
||||
strncpy(path, dump_dir, remaining);
|
||||
remaining -= dirPathLength;
|
||||
path += dirPathLength;
|
||||
|
|
|
|||
|
|
@ -167,48 +167,34 @@ const U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 + 1 for good luc
|
|||
//
|
||||
// defined for U16, U32, U64, S16, S32, S64, :
|
||||
// llclampb(a) // clamps a to [0 .. 255]
|
||||
//
|
||||
//
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline auto llmax(T1 d1, T2 d2)
|
||||
// recursion tail
|
||||
template <typename T>
|
||||
inline auto llmax(T data)
|
||||
{
|
||||
return (d1 > d2) ? d1 : d2;
|
||||
return data;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
inline auto llmax(T1 d1, T2 d2, T3 d3)
|
||||
template <typename T0, typename T1, typename... Ts>
|
||||
inline auto llmax(T0 d0, T1 d1, Ts... rest)
|
||||
{
|
||||
auto r = llmax(d1,d2);
|
||||
return llmax(r, d3);
|
||||
auto maxrest = llmax(d1, rest...);
|
||||
return (d0 > maxrest)? d0 : maxrest;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
inline auto llmax(T1 d1, T2 d2, T3 d3, T4 d4)
|
||||
// recursion tail
|
||||
template <typename T>
|
||||
inline auto llmin(T data)
|
||||
{
|
||||
auto r1 = llmax(d1,d2);
|
||||
auto r2 = llmax(d3,d4);
|
||||
return llmax(r1, r2);
|
||||
return data;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline auto llmin(T1 d1, T2 d2)
|
||||
template <typename T0, typename T1, typename... Ts>
|
||||
inline auto llmin(T0 d0, T1 d1, Ts... rest)
|
||||
{
|
||||
return (d1 < d2) ? d1 : d2;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
inline auto llmin(T1 d1, T2 d2, T3 d3)
|
||||
{
|
||||
auto r = llmin(d1,d2);
|
||||
return (r < d3 ? r : d3);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
inline auto llmin(T1 d1, T2 d2, T3 d3, T4 d4)
|
||||
{
|
||||
auto r1 = llmin(d1,d2);
|
||||
auto r2 = llmin(d3,d4);
|
||||
return llmin(r1, r2);
|
||||
auto minrest = llmin(d1, rest...);
|
||||
return (d0 < minrest) ? d0 : minrest;
|
||||
}
|
||||
|
||||
template <typename A, typename MIN, typename MAX>
|
||||
|
|
|
|||
|
|
@ -204,30 +204,35 @@ public:
|
|||
LLSD packet(LLSDMap("pump", pump)("data", data));
|
||||
|
||||
std::ostringstream buffer;
|
||||
buffer << LLSDNotationStreamer(packet);
|
||||
// SL-18330: for large data blocks, it's much faster to parse binary
|
||||
// LLSD than notation LLSD. Use serialize(LLSD_BINARY) rather than
|
||||
// directly calling LLSDBinaryFormatter because, unlike the latter,
|
||||
// serialize() prepends the relevant header, needed by a general-
|
||||
// purpose LLSD parser to distinguish binary from notation.
|
||||
LLSDSerialize::serialize(packet, buffer, LLSDSerialize::LLSD_BINARY,
|
||||
LLSDFormatter::OPTIONS_NONE);
|
||||
|
||||
/*==========================================================================*|
|
||||
// DEBUGGING ONLY: don't copy str() if we can avoid it.
|
||||
std::string strdata(buffer.str());
|
||||
if (std::size_t(buffer.tellp()) != strdata.length())
|
||||
{
|
||||
LL_ERRS("LLLeap") << "tellp() -> " << buffer.tellp() << " != "
|
||||
LL_ERRS("LLLeap") << "tellp() -> " << static_cast<U64>(buffer.tellp()) << " != "
|
||||
<< "str().length() -> " << strdata.length() << LL_ENDL;
|
||||
}
|
||||
// DEBUGGING ONLY: reading back is terribly inefficient.
|
||||
std::istringstream readback(strdata);
|
||||
LLSD echo;
|
||||
LLPointer<LLSDParser> parser(new LLSDNotationParser());
|
||||
S32 parse_status(parser->parse(readback, echo, strdata.length()));
|
||||
if (parse_status == LLSDParser::PARSE_FAILURE)
|
||||
bool parse_status(LLSDSerialize::deserialize(echo, readback, strdata.length()));
|
||||
if (! parse_status)
|
||||
{
|
||||
LL_ERRS("LLLeap") << "LLSDNotationParser() cannot parse output of "
|
||||
<< "LLSDNotationStreamer()" << LL_ENDL;
|
||||
LL_ERRS("LLLeap") << "LLSDSerialize::deserialize() cannot parse output of "
|
||||
<< "LLSDSerialize::serialize(LLSD_BINARY)" << LL_ENDL;
|
||||
}
|
||||
if (! llsd_equals(echo, packet))
|
||||
{
|
||||
LL_ERRS("LLLeap") << "LLSDNotationParser() produced different LLSD "
|
||||
<< "than passed to LLSDNotationStreamer()" << LL_ENDL;
|
||||
LL_ERRS("LLLeap") << "LLSDSerialize::deserialize() returned different LLSD "
|
||||
<< "than passed to LLSDSerialize::serialize()" << LL_ENDL;
|
||||
}
|
||||
|*==========================================================================*/
|
||||
|
||||
|
|
@ -314,9 +319,17 @@ public:
|
|||
LL_DEBUGS("LLLeap") << "needed " << mExpect << " bytes, got "
|
||||
<< childout.size() << ", parsing LLSD" << LL_ENDL;
|
||||
LLSD data;
|
||||
#if 1
|
||||
// specifically require notation LLSD from child
|
||||
LLPointer<LLSDParser> parser(new LLSDNotationParser());
|
||||
S32 parse_status(parser->parse(childout.get_istream(), data, mExpect));
|
||||
if (parse_status == LLSDParser::PARSE_FAILURE)
|
||||
#else
|
||||
// SL-18330: accept any valid LLSD serialization format from child
|
||||
// Unfortunately this runs into trouble we have not yet debugged.
|
||||
bool parse_status(LLSDSerialize::deserialize(data, childout.get_istream(), mExpect));
|
||||
if (! parse_status)
|
||||
#endif
|
||||
{
|
||||
bad_protocol("unparseable LLSD data");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ LLMD5::LLMD5()
|
|||
// operation, processing another message block, and updating the
|
||||
// context.
|
||||
|
||||
void LLMD5::update (const uint1 *input, const size_t input_length) {
|
||||
void LLMD5::update (const uint8_t *input, const size_t input_length) {
|
||||
|
||||
size_t input_index, buffer_index;
|
||||
size_t buffer_space; // how much space is left in buffer
|
||||
|
|
@ -189,7 +189,7 @@ void LLMD5::finalize (){
|
|||
|
||||
unsigned char bits[8]; /* Flawfinder: ignore */
|
||||
size_t index, padLen;
|
||||
static uint1 PADDING[64]={
|
||||
static uint8_t PADDING[64]={
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
|
@ -201,8 +201,8 @@ void LLMD5::finalize (){
|
|||
}
|
||||
|
||||
// Save number of bits.
|
||||
// Treat count, a uint64_t, as uint4[2].
|
||||
encode (bits, reinterpret_cast<uint4*>(&count), 8);
|
||||
// Treat count, a uint64_t, as uint32_t[2].
|
||||
encode (bits, reinterpret_cast<uint32_t*>(&count), 8);
|
||||
|
||||
// Pad out to 56 mod 64.
|
||||
index = size_t((count >> 3) & 0x3f);
|
||||
|
|
@ -412,7 +412,7 @@ Rotation is separate from addition to prevent recomputation.
|
|||
// LLMD5 basic transformation. Transforms state based on block.
|
||||
void LLMD5::transform (const U8 block[64]){
|
||||
|
||||
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
decode (x, block, 64);
|
||||
|
||||
|
|
@ -496,38 +496,38 @@ void LLMD5::transform (const U8 block[64]){
|
|||
state[3] += d;
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset ( (uint1 *) x, 0, sizeof(x));
|
||||
memset ( (uint8_t *) x, 0, sizeof(x));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||
// Encodes input (uint32_t) into output (unsigned char). Assumes len is
|
||||
// a multiple of 4.
|
||||
void LLMD5::encode (uint1 *output, const uint4 *input, const size_t len) {
|
||||
void LLMD5::encode (uint8_t *output, const uint32_t *input, const size_t len) {
|
||||
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (uint1) (input[i] & 0xff);
|
||||
output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
|
||||
output[j] = (uint8_t) (input[i] & 0xff);
|
||||
output[j+1] = (uint8_t) ((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (uint8_t) ((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (uint8_t) ((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||
// Decodes input (unsigned char) into output (uint32_t). Assumes len is
|
||||
// a multiple of 4.
|
||||
void LLMD5::decode (uint4 *output, const uint1 *input, const size_t len){
|
||||
void LLMD5::decode (uint32_t *output, const uint8_t *input, const size_t len){
|
||||
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
|
||||
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
|
||||
output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
|
||||
(((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ documentation and/or software.
|
|||
|
||||
*/
|
||||
|
||||
#include <cstdint> // uint32_t et al.
|
||||
|
||||
// use for the raw digest output
|
||||
const int MD5RAW_BYTES = 16;
|
||||
|
||||
|
|
@ -75,18 +77,13 @@ const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null
|
|||
const int MD5HEX_STR_BYTES = 32; // message system fixed size
|
||||
|
||||
class LL_COMMON_API LLMD5 {
|
||||
// first, some types:
|
||||
typedef unsigned int uint4; // assumes integer is 4 words long
|
||||
typedef unsigned short int uint2; // assumes short integer is 2 words long
|
||||
typedef unsigned char uint1; // assumes char is 1 word long
|
||||
|
||||
// how many bytes to grab at a time when checking files
|
||||
static const int BLOCK_LEN;
|
||||
|
||||
public:
|
||||
// methods for controlled operation:
|
||||
LLMD5 (); // simple initializer
|
||||
void update (const uint1 *input, const size_t input_length);
|
||||
void update (const uint8_t *input, const size_t input_length);
|
||||
void update (std::istream& stream);
|
||||
void update (FILE *file);
|
||||
void update (const std::string& str);
|
||||
|
|
@ -109,19 +106,19 @@ private:
|
|||
|
||||
|
||||
// next, the private data:
|
||||
uint4 state[4];
|
||||
uint32_t state[4];
|
||||
uint64_t count; // number of *bits*, mod 2^64
|
||||
uint1 buffer[64]; // input buffer
|
||||
uint1 digest[16];
|
||||
uint1 finalized;
|
||||
uint8_t buffer[64]; // input buffer
|
||||
uint8_t digest[16];
|
||||
uint8_t finalized;
|
||||
|
||||
// last, the private methods, mostly static:
|
||||
void init (); // called by all constructors
|
||||
void transform (const uint1 *buffer); // does the real update work. Note
|
||||
void transform (const uint8_t *buffer); // does the real update work. Note
|
||||
// that length is implied to be 64.
|
||||
|
||||
static void encode (uint1 *dest, const uint4 *src, const size_t length);
|
||||
static void decode (uint4 *dest, const uint1 *src, const size_t length);
|
||||
static void encode (uint8_t *dest, const uint32_t *src, const size_t length);
|
||||
static void decode (uint32_t *dest, const uint8_t *src, const size_t length);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#endif
|
||||
|
||||
#include "lldate.h"
|
||||
#include "llmemorystream.h"
|
||||
#include "llsd.h"
|
||||
#include "llstring.h"
|
||||
#include "lluri.h"
|
||||
|
|
@ -64,6 +65,23 @@ const std::string LLSD_NOTATION_HEADER("llsd/notation");
|
|||
#define windowBits 15
|
||||
#define ENABLE_ZLIB_GZIP 32
|
||||
|
||||
// If we published this in llsdserialize.h, we could use it in the
|
||||
// implementation of LLSDOStreamer's operator<<().
|
||||
template <class Formatter>
|
||||
void format_using(const LLSD& data, std::ostream& ostr,
|
||||
LLSDFormatter::EFormatterOptions options=LLSDFormatter::OPTIONS_PRETTY_BINARY)
|
||||
{
|
||||
LLPointer<Formatter> f{ new Formatter };
|
||||
f->format(data, ostr, options);
|
||||
}
|
||||
|
||||
template <class Parser>
|
||||
S32 parse_using(std::istream& istr, LLSD& data, size_t max_bytes, S32 max_depth=-1)
|
||||
{
|
||||
LLPointer<Parser> p{ new Parser };
|
||||
return p->parse(istr, data, max_bytes, max_depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* LLSDSerialize
|
||||
*/
|
||||
|
|
@ -86,10 +104,10 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize
|
|||
f = new LLSDXMLFormatter;
|
||||
break;
|
||||
|
||||
case LLSD_NOTATION:
|
||||
str << "<? " << LLSD_NOTATION_HEADER << " ?>\n";
|
||||
f = new LLSDNotationFormatter;
|
||||
break;
|
||||
case LLSD_NOTATION:
|
||||
str << "<? " << LLSD_NOTATION_HEADER << " ?>\n";
|
||||
f = new LLSDNotationFormatter;
|
||||
break;
|
||||
|
||||
default:
|
||||
LL_WARNS() << "serialize request for unknown ELLSD_Serialize" << LL_ENDL;
|
||||
|
|
@ -104,18 +122,37 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize
|
|||
// static
|
||||
bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, llssize max_bytes)
|
||||
{
|
||||
LLPointer<LLSDParser> p = NULL;
|
||||
char hdr_buf[MAX_HDR_LEN + 1] = ""; /* Flawfinder: ignore */
|
||||
int i;
|
||||
int inbuf = 0;
|
||||
bool legacy_no_header = false;
|
||||
bool fail_if_not_legacy = false;
|
||||
std::string header;
|
||||
|
||||
/*
|
||||
* Get the first line before anything.
|
||||
*/
|
||||
str.get(hdr_buf, MAX_HDR_LEN, '\n');
|
||||
/*
|
||||
* Get the first line before anything. Don't read more than max_bytes:
|
||||
* this get() overload reads no more than (count-1) bytes into the
|
||||
* specified buffer. In the usual case when max_bytes exceeds
|
||||
* sizeof(hdr_buf), get() will read no more than sizeof(hdr_buf)-2.
|
||||
*/
|
||||
llssize max_hdr_read = MAX_HDR_LEN;
|
||||
if (max_bytes != LLSDSerialize::SIZE_UNLIMITED)
|
||||
{
|
||||
max_hdr_read = llmin(max_bytes + 1, max_hdr_read);
|
||||
}
|
||||
str.get(hdr_buf, max_hdr_read, '\n');
|
||||
auto inbuf = str.gcount();
|
||||
|
||||
// https://en.cppreference.com/w/cpp/io/basic_istream/get
|
||||
// When the get() above sees the specified delimiter '\n', it stops there
|
||||
// without pulling it from the stream. If it turns out that the stream
|
||||
// does NOT contain a header, and the content includes meaningful '\n',
|
||||
// it's important to pull that into hdr_buf too.
|
||||
if (inbuf < max_bytes && str.get(hdr_buf[inbuf]))
|
||||
{
|
||||
// got the delimiting '\n'
|
||||
++inbuf;
|
||||
// None of the following requires that hdr_buf contain a final '\0'
|
||||
// byte. We could store one if needed, since even the incremented
|
||||
// inbuf won't exceed sizeof(hdr_buf)-1, but there's no need.
|
||||
}
|
||||
std::string header{ hdr_buf, static_cast<std::string::size_type>(inbuf) };
|
||||
if (str.fail())
|
||||
{
|
||||
str.clear();
|
||||
|
|
@ -123,79 +160,97 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, llssize max_bytes)
|
|||
}
|
||||
|
||||
if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */
|
||||
{
|
||||
legacy_no_header = true;
|
||||
inbuf = (int)str.gcount();
|
||||
{ // Create a LLSD XML parser, and parse the first chunk read above.
|
||||
LLSDXMLParser x;
|
||||
x.parsePart(hdr_buf, inbuf); // Parse the first part that was already read
|
||||
auto parsed = x.parse(str, sd, max_bytes - inbuf); // Parse the rest of it
|
||||
// Formally we should probably check (parsed != PARSE_FAILURE &&
|
||||
// parsed > 0), but since PARSE_FAILURE is -1, this suffices.
|
||||
return (parsed > 0);
|
||||
}
|
||||
else
|
||||
|
||||
if (fail_if_not_legacy)
|
||||
{
|
||||
if (fail_if_not_legacy)
|
||||
goto fail;
|
||||
/*
|
||||
* Remove the newline chars
|
||||
*/
|
||||
for (i = 0; i < MAX_HDR_LEN; i++)
|
||||
{
|
||||
if (hdr_buf[i] == 0 || hdr_buf[i] == '\r' ||
|
||||
hdr_buf[i] == '\n')
|
||||
{
|
||||
hdr_buf[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
header = hdr_buf;
|
||||
LL_WARNS() << "deserialize LLSD parse failure" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string::size_type start = std::string::npos;
|
||||
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);
|
||||
}
|
||||
if ((start == std::string::npos) || (end == std::string::npos))
|
||||
goto fail;
|
||||
/*
|
||||
* Remove the newline chars
|
||||
*/
|
||||
std::string::size_type lastchar = header.find_last_not_of("\r\n");
|
||||
if (lastchar != std::string::npos)
|
||||
{
|
||||
// It's important that find_last_not_of() returns size_type, which is
|
||||
// why lastchar explicitly declares the type above. erase(size_type)
|
||||
// erases from that offset to the end of the string, whereas
|
||||
// erase(iterator) erases only a single character.
|
||||
header.erase(lastchar+1);
|
||||
}
|
||||
|
||||
header = header.substr(start, end - start);
|
||||
ws(str);
|
||||
// trim off the <? ... ?> header syntax
|
||||
auto start = header.find_first_not_of("<? ");
|
||||
if (start != std::string::npos)
|
||||
{
|
||||
auto end = header.find_first_of(" ?", start);
|
||||
if (end != std::string::npos)
|
||||
{
|
||||
header = header.substr(start, end - start);
|
||||
ws(str);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Create the parser as appropriate
|
||||
*/
|
||||
if (legacy_no_header)
|
||||
{ // Create a LLSD XML parser, and parse the first chunk read above
|
||||
LLSDXMLParser* x = new LLSDXMLParser();
|
||||
x->parsePart(hdr_buf, inbuf); // Parse the first part that was already read
|
||||
x->parseLines(str, sd); // Parse the rest of it
|
||||
delete x;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (header == LLSD_BINARY_HEADER)
|
||||
if (0 == LLStringUtil::compareInsensitive(header, LLSD_BINARY_HEADER))
|
||||
{
|
||||
p = new LLSDBinaryParser;
|
||||
return (parse_using<LLSDBinaryParser>(str, sd, max_bytes-inbuf) > 0);
|
||||
}
|
||||
else if (header == LLSD_XML_HEADER)
|
||||
else if (0 == LLStringUtil::compareInsensitive(header, LLSD_XML_HEADER))
|
||||
{
|
||||
p = new LLSDXMLParser;
|
||||
return (parse_using<LLSDXMLParser>(str, sd, max_bytes-inbuf) > 0);
|
||||
}
|
||||
else if (header == LLSD_NOTATION_HEADER)
|
||||
else if (0 == LLStringUtil::compareInsensitive(header, LLSD_NOTATION_HEADER))
|
||||
{
|
||||
p = new LLSDNotationParser;
|
||||
return (parse_using<LLSDNotationParser>(str, sd, max_bytes-inbuf) > 0);
|
||||
}
|
||||
else
|
||||
else // no header we recognize
|
||||
{
|
||||
LL_WARNS() << "deserialize request for unknown ELLSD_Serialize" << LL_ENDL;
|
||||
LLPointer<LLSDParser> p;
|
||||
if (inbuf && hdr_buf[0] == '<')
|
||||
{
|
||||
// looks like XML
|
||||
LL_DEBUGS() << "deserialize request with no header, assuming XML" << LL_ENDL;
|
||||
p = new LLSDXMLParser;
|
||||
}
|
||||
else
|
||||
{
|
||||
// assume notation
|
||||
LL_DEBUGS() << "deserialize request with no header, assuming notation" << LL_ENDL;
|
||||
p = new LLSDNotationParser;
|
||||
}
|
||||
// Since we've already read 'inbuf' bytes into 'hdr_buf', prepend that
|
||||
// data to whatever remains in 'str'.
|
||||
LLMemoryStreamBuf already(reinterpret_cast<const U8*>(hdr_buf), inbuf);
|
||||
cat_streambuf prebuff(&already, str.rdbuf());
|
||||
std::istream prepend(&prebuff);
|
||||
#if 1
|
||||
return (p->parse(prepend, sd, max_bytes) > 0);
|
||||
#else
|
||||
// debugging the reconstituted 'prepend' stream
|
||||
// allocate a buffer that we hope is big enough for the whole thing
|
||||
std::vector<char> wholemsg((max_bytes == size_t(SIZE_UNLIMITED))? 1024 : max_bytes);
|
||||
prepend.read(wholemsg.data(), std::min(max_bytes, wholemsg.size()));
|
||||
LLMemoryStream replay(reinterpret_cast<const U8*>(wholemsg.data()), prepend.gcount());
|
||||
auto success{ p->parse(replay, sd, prepend.gcount()) > 0 };
|
||||
{
|
||||
LL_DEBUGS() << (success? "parsed: $$" : "failed: '")
|
||||
<< std::string(wholemsg.data(), llmin(prepend.gcount(), 100)) << "$$"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
return success;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (p.notNull())
|
||||
{
|
||||
p->parse(str, sd, max_bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
fail:
|
||||
LL_WARNS() << "deserialize LLSD parse failure" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2195,7 +2250,7 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32
|
|||
U8* result = NULL;
|
||||
llssize cur_size = 0;
|
||||
z_stream strm;
|
||||
|
||||
|
||||
constexpr U32 CHUNK = 1024 * 512;
|
||||
|
||||
static thread_local std::unique_ptr<U8[]> out;
|
||||
|
|
@ -2399,7 +2454,7 @@ U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size
|
|||
return result;
|
||||
}
|
||||
|
||||
char* strip_deprecated_header(char* in, llssize& cur_size, U32* header_size)
|
||||
char* strip_deprecated_header(char* in, llssize& cur_size, llssize* header_size)
|
||||
{
|
||||
const char* deprecated_header = "<? LLSD/Binary ?>";
|
||||
constexpr size_t deprecated_header_size = 17;
|
||||
|
|
|
|||
|
|
@ -873,5 +873,5 @@ LL_COMMON_API std::string zip_llsd(LLSD& data);
|
|||
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, size_t& outsize,std::istream& is, S32 size);
|
||||
|
||||
// returns a pointer to the array or past the array if the deprecated header exists
|
||||
LL_COMMON_API char* strip_deprecated_header(char* in, llssize& cur_size, U32* header_size = nullptr);
|
||||
LL_COMMON_API char* strip_deprecated_header(char* in, llssize& cur_size, llssize* header_size = nullptr);
|
||||
#endif // LL_LLSDSERIALIZE_H
|
||||
|
|
|
|||
|
|
@ -513,3 +513,29 @@ std::istream& operator>>(std::istream& str, const char *tocheck)
|
|||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
int cat_streambuf::underflow()
|
||||
{
|
||||
if (gptr() == egptr())
|
||||
{
|
||||
// here because our buffer is empty
|
||||
std::streamsize size = 0;
|
||||
// Until we've run out of mInputs, try reading the first of them
|
||||
// into mBuffer. If that fetches some characters, break the loop.
|
||||
while (! mInputs.empty()
|
||||
&& ! (size = mInputs.front()->sgetn(mBuffer.data(), mBuffer.size())))
|
||||
{
|
||||
// We tried to read mInputs.front() but got zero characters.
|
||||
// Discard the first streambuf and try the next one.
|
||||
mInputs.pop_front();
|
||||
}
|
||||
// Either we ran out of mInputs or we succeeded in reading some
|
||||
// characters, that is, size != 0. Tell base class what we have.
|
||||
setg(mBuffer.data(), mBuffer.data(), mBuffer.data() + size);
|
||||
}
|
||||
// If we fell out of the above loop with mBuffer still empty, return
|
||||
// eof(), otherwise return the next character.
|
||||
return (gptr() == egptr())
|
||||
? std::char_traits<char>::eof()
|
||||
: std::char_traits<char>::to_int_type(*gptr());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@
|
|||
#ifndef LL_STREAM_TOOLS_H
|
||||
#define LL_STREAM_TOOLS_H
|
||||
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// unless specifed otherwise these all return input_stream.good()
|
||||
|
||||
|
|
@ -113,6 +115,27 @@ LL_COMMON_API std::streamsize fullread(
|
|||
|
||||
LL_COMMON_API std::istream& operator>>(std::istream& str, const char *tocheck);
|
||||
|
||||
/**
|
||||
* cat_streambuf is a std::streambuf subclass that accepts a variadic number
|
||||
* of std::streambuf* (e.g. some_istream.rdbuf()) and virtually concatenates
|
||||
* their contents.
|
||||
*/
|
||||
// derived from https://stackoverflow.com/a/49441066/5533635
|
||||
class cat_streambuf: public std::streambuf
|
||||
{
|
||||
private:
|
||||
std::deque<std::streambuf*> mInputs;
|
||||
std::vector<char> mBuffer;
|
||||
|
||||
public:
|
||||
// only valid for std::streambuf* arguments
|
||||
template <typename... Inputs>
|
||||
cat_streambuf(Inputs... inputs):
|
||||
mInputs{inputs...},
|
||||
mBuffer(1024)
|
||||
{}
|
||||
|
||||
int underflow() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -577,10 +577,12 @@ S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat )
|
|||
// PeriodicRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
PeriodicRecording::PeriodicRecording( S32 num_periods, EPlayState state)
|
||||
PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
||||
: mAutoResize(num_periods == 0),
|
||||
mCurPeriod(0),
|
||||
mNumRecordedPeriods(0),
|
||||
// This guarantee that mRecordingPeriods cannot be empty is essential for
|
||||
// code in several methods.
|
||||
mRecordingPeriods(num_periods ? num_periods : 1)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
|
|
@ -596,18 +598,19 @@ PeriodicRecording::~PeriodicRecording()
|
|||
|
||||
void PeriodicRecording::nextPeriod()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (mAutoResize)
|
||||
{
|
||||
mRecordingPeriods.push_back(Recording());
|
||||
}
|
||||
|
||||
Recording& old_recording = getCurRecording();
|
||||
mCurPeriod = (mCurPeriod + 1) % mRecordingPeriods.size();
|
||||
inci(mCurPeriod);
|
||||
old_recording.splitTo(getCurRecording());
|
||||
|
||||
mNumRecordedPeriods = mRecordingPeriods.empty()? 0 :
|
||||
llmin(mRecordingPeriods.size() - 1, mNumRecordedPeriods + 1);
|
||||
// Since mRecordingPeriods always has at least one entry, we can always
|
||||
// safely subtract 1 from its size().
|
||||
mNumRecordedPeriods = llmin(mRecordingPeriods.size() - 1, mNumRecordedPeriods + 1);
|
||||
}
|
||||
|
||||
void PeriodicRecording::appendRecording(Recording& recording)
|
||||
|
|
@ -620,31 +623,29 @@ void PeriodicRecording::appendRecording(Recording& recording)
|
|||
|
||||
void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (other.mRecordingPeriods.empty()) return;
|
||||
|
||||
getCurRecording().update();
|
||||
other.getCurRecording().update();
|
||||
|
||||
const auto other_recording_slots = other.mRecordingPeriods.size();
|
||||
|
||||
const auto other_num_recordings = other.getNumRecordedPeriods();
|
||||
const auto other_current_recording_index = other.mCurPeriod;
|
||||
const auto other_oldest_recording_index = (other_current_recording_index + other_recording_slots - other_num_recordings) % other_recording_slots;
|
||||
const auto other_oldest_recording_index = other.previ(other_current_recording_index, other_num_recordings);
|
||||
|
||||
// append first recording into our current slot
|
||||
getCurRecording().appendRecording(other.mRecordingPeriods[other_oldest_recording_index]);
|
||||
|
||||
// from now on, add new recordings for everything after the first
|
||||
auto other_index = (other_oldest_recording_index + 1) % other_recording_slots;
|
||||
auto other_index = other.nexti(other_oldest_recording_index);
|
||||
|
||||
if (mAutoResize)
|
||||
{
|
||||
// push back recordings for everything in the middle
|
||||
auto other_index = (other_oldest_recording_index + 1) % other_recording_slots;
|
||||
while (other_index != other_current_recording_index)
|
||||
{
|
||||
mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]);
|
||||
other_index = (other_index + 1) % other_recording_slots;
|
||||
other.inci(other_index);
|
||||
}
|
||||
|
||||
// add final recording, if it wasn't already added as the first
|
||||
|
|
@ -653,36 +654,25 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
|
|||
mRecordingPeriods.push_back(other.mRecordingPeriods[other_current_recording_index]);
|
||||
}
|
||||
|
||||
mCurPeriod = mRecordingPeriods.empty()? 0 : mRecordingPeriods.size() - 1;
|
||||
// mRecordingPeriods is never empty()
|
||||
mCurPeriod = mRecordingPeriods.size() - 1;
|
||||
mNumRecordedPeriods = mCurPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 num_to_copy = llmin((S32)mRecordingPeriods.size(), (S32)other_num_recordings);
|
||||
|
||||
std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin() + other_index ;
|
||||
std::vector<Recording>::iterator dest_it = mRecordingPeriods.begin() + mCurPeriod;
|
||||
|
||||
auto num_to_copy = llmin(mRecordingPeriods.size(), other_num_recordings);
|
||||
// already consumed the first recording from other, so start counting at 1
|
||||
for(S32 i = 1; i < num_to_copy; i++)
|
||||
for (size_t n = 1, srci = other_index, dsti = mCurPeriod;
|
||||
n < num_to_copy;
|
||||
++n, other.inci(srci), inci(dsti))
|
||||
{
|
||||
*dest_it = *src_it;
|
||||
|
||||
if (++src_it == other.mRecordingPeriods.end())
|
||||
{
|
||||
src_it = other.mRecordingPeriods.begin();
|
||||
}
|
||||
|
||||
if (++dest_it == mRecordingPeriods.end())
|
||||
{
|
||||
dest_it = mRecordingPeriods.begin();
|
||||
}
|
||||
mRecordingPeriods[dsti] = other.mRecordingPeriods[srci];
|
||||
}
|
||||
|
||||
|
||||
// want argument to % to be positive, otherwise result could be negative and thus out of bounds
|
||||
llassert(num_to_copy >= 1);
|
||||
// advance to last recording period copied, and make that our current period
|
||||
mCurPeriod = (mCurPeriod + num_to_copy - 1) % mRecordingPeriods.size();
|
||||
inci(mCurPeriod, num_to_copy - 1);
|
||||
mNumRecordedPeriods = llmin(mRecordingPeriods.size() - 1, mNumRecordedPeriods + num_to_copy - 1);
|
||||
}
|
||||
|
||||
|
|
@ -694,13 +684,11 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
|
|||
|
||||
F64Seconds PeriodicRecording::getDuration() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
F64Seconds duration;
|
||||
auto num_periods = mRecordingPeriods.size();
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
for (size_t n = 0; n < mRecordingPeriods.size(); ++n)
|
||||
{
|
||||
auto index = (mCurPeriod + num_periods - i) % num_periods;
|
||||
duration += mRecordingPeriods[index].getDuration();
|
||||
duration += mRecordingPeriods[nexti(mCurPeriod, n)].getDuration();
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
|
@ -737,16 +725,14 @@ const Recording& PeriodicRecording::getCurRecording() const
|
|||
|
||||
Recording& PeriodicRecording::getPrevRecording( size_t offset )
|
||||
{
|
||||
auto num_periods = mRecordingPeriods.size();
|
||||
offset = llclamp(offset, 0, num_periods - 1);
|
||||
return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods];
|
||||
// reuse const implementation, but return non-const reference
|
||||
return const_cast<Recording&>(
|
||||
const_cast<const PeriodicRecording*>(this)->getPrevRecording(offset));
|
||||
}
|
||||
|
||||
const Recording& PeriodicRecording::getPrevRecording( size_t offset ) const
|
||||
{
|
||||
auto num_periods = mRecordingPeriods.size();
|
||||
offset = llclamp(offset, 0, num_periods - 1);
|
||||
return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods];
|
||||
return mRecordingPeriods[previ(mCurPeriod, offset)];
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleStart()
|
||||
|
|
@ -789,14 +775,14 @@ void PeriodicRecording::handleSplitTo(PeriodicRecording& other)
|
|||
getCurRecording().splitTo(other.getCurRecording());
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
F64 min_val = std::numeric_limits<F64>::max();
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -811,14 +797,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, siz
|
|||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
F64 max_val = std::numeric_limits<F64>::min();
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -834,7 +820,7 @@ F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, siz
|
|||
}
|
||||
|
||||
// calculates means using aggregates per period
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
|
@ -842,7 +828,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, si
|
|||
F64 mean = 0;
|
||||
S32 valid_period_count = 0;
|
||||
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -857,7 +843,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, si
|
|||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
|
@ -866,7 +852,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat
|
|||
F64 sum_of_squares = 0;
|
||||
S32 valid_period_count = 0;
|
||||
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -882,14 +868,14 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat
|
|||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
F64 min_val = std::numeric_limits<F64>::max();
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -904,14 +890,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, si
|
|||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/)
|
||||
F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
F64 max_val = std::numeric_limits<F64>::min();
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -927,7 +913,7 @@ F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, siz
|
|||
}
|
||||
|
||||
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
|
@ -935,7 +921,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, s
|
|||
S32 valid_period_count = 0;
|
||||
F64 mean = 0;
|
||||
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -950,13 +936,13 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, s
|
|||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
std::vector<F64> buf;
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.getDuration() > (F32Seconds)0.f)
|
||||
|
|
@ -976,7 +962,7 @@ F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat,
|
|||
return F64((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]);
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
|
@ -985,7 +971,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula
|
|||
S32 valid_period_count = 0;
|
||||
F64 sum_of_squares = 0;
|
||||
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -1002,13 +988,13 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula
|
|||
}
|
||||
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes min_val(std::numeric_limits<F64>::max());
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
min_val = llmin(min_val, recording.getMin(stat));
|
||||
|
|
@ -1022,13 +1008,13 @@ F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, size_t n
|
|||
return getPeriodMin(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/)
|
||||
F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes max_val(0.0);
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
max_val = llmax(max_val, recording.getMax(stat));
|
||||
|
|
@ -1042,14 +1028,14 @@ F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, size_t n
|
|||
return getPeriodMax(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes mean(0);
|
||||
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
mean += recording.getMean(stat);
|
||||
|
|
@ -1063,7 +1049,7 @@ F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, size_t
|
|||
return getPeriodMean(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ )
|
||||
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
|
@ -1072,7 +1058,7 @@ F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAc
|
|||
S32 valid_period_count = 0;
|
||||
F64 sum_of_squares = 0;
|
||||
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "lltimer.h"
|
||||
#include "lltraceaccumulators.h"
|
||||
#include "llpointer.h"
|
||||
#include <limits>
|
||||
|
||||
class LLStopWatchControlsMixinCommon
|
||||
{
|
||||
|
|
@ -330,7 +331,7 @@ namespace LLTrace
|
|||
: public LLStopWatchControlsMixin<PeriodicRecording>
|
||||
{
|
||||
public:
|
||||
PeriodicRecording(S32 num_periods, EPlayState state = STOPPED);
|
||||
PeriodicRecording(size_t num_periods, EPlayState state = STOPPED);
|
||||
~PeriodicRecording();
|
||||
|
||||
void nextPeriod();
|
||||
|
|
@ -353,7 +354,7 @@ namespace LLTrace
|
|||
Recording snapshotCurRecording() const;
|
||||
|
||||
template <typename T>
|
||||
auto getSampleCount(const StatType<T>& stat, size_t num_periods = S32_MAX)
|
||||
auto getSampleCount(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
|
@ -373,14 +374,14 @@ namespace LLTrace
|
|||
|
||||
// catch all for stats that have a defined sum
|
||||
template <typename T>
|
||||
typename T::value_t getPeriodMin(const StatType<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename T::value_t getPeriodMin(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
typename T::value_t min_val(std::numeric_limits<typename T::value_t>::max());
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -396,39 +397,39 @@ namespace LLTrace
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
T getPeriodMin(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
T getPeriodMin(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64 getPeriodMin(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodMin(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64 getPeriodMin(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodMin(const StatType<EventAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64Kilobytes getPeriodMin(const MemStatHandle& stat, size_t num_periods = S32_MAX);
|
||||
F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMin(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t min_val(std::numeric_limits<F64>::max());
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
min_val = llmin(min_val, recording.getPerSec(stat));
|
||||
|
|
@ -437,7 +438,7 @@ namespace LLTrace
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMinPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
|
|
@ -449,14 +450,14 @@ namespace LLTrace
|
|||
|
||||
// catch all for stats that have a defined sum
|
||||
template <typename T>
|
||||
typename T::value_t getPeriodMax(const StatType<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename T::value_t getPeriodMax(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
typename T::value_t max_val(std::numeric_limits<typename T::value_t>::min());
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
|
|
@ -472,39 +473,39 @@ namespace LLTrace
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
T getPeriodMax(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
T getPeriodMax(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64 getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64 getPeriodMax(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodMax(const StatType<EventAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64Kilobytes getPeriodMax(const MemStatHandle& stat, size_t num_periods = S32_MAX);
|
||||
F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMax(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 max_val = std::numeric_limits<F64>::min();
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
max_val = llmax(max_val, recording.getPerSec(stat));
|
||||
|
|
@ -513,7 +514,7 @@ namespace LLTrace
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMaxPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
|
|
@ -525,14 +526,14 @@ namespace LLTrace
|
|||
|
||||
// catch all for stats that have a defined sum
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t mean(0);
|
||||
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.getDuration() > (F32Seconds)0.f)
|
||||
|
|
@ -546,39 +547,39 @@ namespace LLTrace
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
F64 getPeriodMean(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodMean(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64 getPeriodMean(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodMean(const StatType<EventAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64Kilobytes getPeriodMean(const MemStatHandle& stat, size_t num_periods = S32_MAX);
|
||||
F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMean(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t mean = 0;
|
||||
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.getDuration() > (F32Seconds)0.f)
|
||||
|
|
@ -593,64 +594,64 @@ namespace LLTrace
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64 getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
std::vector <typename RelatedTypes<typename T::value_t>::fractional_t> buf;
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.getDuration() > (F32Seconds)0.f)
|
||||
{
|
||||
buf.push_back(recording.getPerSec(stat));
|
||||
}
|
||||
}
|
||||
std::sort(buf.begin(), buf.end());
|
||||
std::vector <typename RelatedTypes<typename T::value_t>::fractional_t> buf;
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.getDuration() > (F32Seconds)0.f)
|
||||
{
|
||||
buf.push_back(recording.getPerSec(stat));
|
||||
}
|
||||
}
|
||||
std::sort(buf.begin(), buf.end());
|
||||
|
||||
return typename RelatedTypes<T>::fractional_t((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]);
|
||||
}
|
||||
return typename RelatedTypes<T>::fractional_t((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMedianPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMedianPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
//
|
||||
// PERIODIC STANDARD DEVIATION
|
||||
//
|
||||
|
||||
F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64 getPeriodStandardDeviation(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64 getPeriodStandardDeviation(const StatType<EventAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX)
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX);
|
||||
F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods = S32_MAX);
|
||||
F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
private:
|
||||
// implementation for LLStopWatchControlsMixin
|
||||
|
|
@ -659,6 +660,35 @@ namespace LLTrace
|
|||
/*virtual*/ void handleReset();
|
||||
/*virtual*/ void handleSplitTo(PeriodicRecording& other);
|
||||
|
||||
// helper methods for wraparound ring-buffer arithmetic
|
||||
inline
|
||||
size_t wrapi(size_t i) const
|
||||
{
|
||||
return i % mRecordingPeriods.size();
|
||||
}
|
||||
|
||||
inline
|
||||
size_t nexti(size_t i, size_t offset=1) const
|
||||
{
|
||||
return wrapi(i + offset);
|
||||
}
|
||||
|
||||
inline
|
||||
size_t previ(size_t i, size_t offset=1) const
|
||||
{
|
||||
auto num_periods = mRecordingPeriods.size();
|
||||
// constrain offset
|
||||
offset = llclamp(offset, 0, num_periods - 1);
|
||||
// add size() so expression can't go (unsigned) "negative"
|
||||
return wrapi(i + num_periods - offset);
|
||||
}
|
||||
|
||||
inline
|
||||
void inci(size_t& i, size_t offset=1) const
|
||||
{
|
||||
i = nexti(i, offset);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Recording> mRecordingPeriods;
|
||||
const bool mAutoResize;
|
||||
|
|
|
|||
|
|
@ -888,7 +888,7 @@ U32 LLUUID::getRandomSeed()
|
|||
seed[7]=(unsigned char)(pid);
|
||||
getSystemTime((uuid_time_t *)(&seed[8]));
|
||||
|
||||
U64 seed64 = HBXXH64((const void*)seed, 16).digest();
|
||||
U64 seed64 = HBXXH64::digest((const void*)seed, 16);
|
||||
return U32(seed64) ^ U32(seed64 >> 32);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,14 @@ public:
|
|||
U16 getCRC16() const;
|
||||
U32 getCRC32() const;
|
||||
|
||||
// Returns a 64 bits digest of the UUID, by XORing its two 64 bits long
|
||||
// words. HB
|
||||
inline U64 getDigest64() const
|
||||
{
|
||||
U64* tmp = (U64*)mData;
|
||||
return tmp[0] ^ tmp[1];
|
||||
}
|
||||
|
||||
static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
|
||||
|
||||
static const LLUUID null;
|
||||
|
|
@ -222,29 +230,23 @@ public:
|
|||
LLAssetID makeAssetID(const LLUUID& session) const;
|
||||
};
|
||||
|
||||
// Generate a hash of an LLUUID object using the boost hash templates.
|
||||
|
||||
// <FS:ND> GCC 4.9 does not like the specialization in form of boost::hash but rather wants a namespace
|
||||
// template <>
|
||||
// struct boost::hash<LLUUID>
|
||||
namespace boost { template <> struct hash<LLUUID>
|
||||
// </FS:ND>
|
||||
// std::hash implementation for LLUUID
|
||||
namespace std
|
||||
{
|
||||
typedef LLUUID argument_type;
|
||||
typedef std::size_t result_type;
|
||||
result_type operator()(argument_type const& s) const
|
||||
{
|
||||
result_type seed(0);
|
||||
template<> struct hash<LLUUID>
|
||||
{
|
||||
inline size_t operator()(const LLUUID& id) const noexcept
|
||||
{
|
||||
return (size_t)id.getDigest64();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < UUID_BYTES; ++i)
|
||||
{
|
||||
boost::hash_combine(seed, s.mData[i]);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
} // <FS:ND/> close namespace
|
||||
// For use with boost containers.
|
||||
inline size_t hash_value(const LLUUID& id) noexcept
|
||||
{
|
||||
return (size_t)id.getDigest64();
|
||||
}
|
||||
|
||||
// <FS:Ansariel> UUID hash calculation
|
||||
struct FSUUIDHash
|
||||
|
|
@ -256,17 +258,4 @@ struct FSUUIDHash
|
|||
};
|
||||
// </FS:Ansariel> UUID hash calculation
|
||||
|
||||
// Adapt boost hash to std hash
|
||||
namespace std
|
||||
{
|
||||
template<> struct hash<LLUUID>
|
||||
{
|
||||
std::size_t operator()(LLUUID const& s) const noexcept
|
||||
{
|
||||
return boost::hash<LLUUID>()(s);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // LL_LLUUID_H
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ typedef unsigned int U32;
|
|||
|
||||
// to express an index that might go negative
|
||||
// (ssize_t is provided by SOME compilers, don't collide)
|
||||
typedef typename std::make_signed<std::size_t>::type llssize; // <FS:Ansariel> Stop Linux complaining
|
||||
typedef typename std::make_signed<std::size_t>::type llssize;
|
||||
|
||||
#if LL_WINDOWS
|
||||
// https://docs.microsoft.com/en-us/cpp/build/reference/zc-wchar-t-wchar-t-is-native-type
|
||||
|
|
|
|||
|
|
@ -109,7 +109,12 @@ namespace tut
|
|||
"import os\n"
|
||||
"import sys\n"
|
||||
"\n"
|
||||
"from llbase import llsd\n"
|
||||
"try:\n"
|
||||
// new freestanding llsd package
|
||||
" import llsd\n"
|
||||
"except ImportError:\n"
|
||||
// older llbase.llsd module
|
||||
" from llbase import llsd\n"
|
||||
"\n"
|
||||
"class ProtocolError(Exception):\n"
|
||||
" def __init__(self, msg, data):\n"
|
||||
|
|
@ -120,26 +125,26 @@ namespace tut
|
|||
" pass\n"
|
||||
"\n"
|
||||
"def get():\n"
|
||||
" hdr = ''\n"
|
||||
" while ':' not in hdr and len(hdr) < 20:\n"
|
||||
" hdr += sys.stdin.read(1)\n"
|
||||
" hdr = []\n"
|
||||
" while b':' not in hdr and len(hdr) < 20:\n"
|
||||
" hdr.append(sys.stdin.buffer.read(1))\n"
|
||||
" if not hdr:\n"
|
||||
" sys.exit(0)\n"
|
||||
" if not hdr.endswith(':'):\n"
|
||||
" if not hdr[-1] == b':':\n"
|
||||
" raise ProtocolError('Expected len:data, got %r' % hdr, hdr)\n"
|
||||
" try:\n"
|
||||
" length = int(hdr[:-1])\n"
|
||||
" length = int(b''.join(hdr[:-1]))\n"
|
||||
" except ValueError:\n"
|
||||
" raise ProtocolError('Non-numeric len %r' % hdr[:-1], hdr[:-1])\n"
|
||||
" parts = []\n"
|
||||
" received = 0\n"
|
||||
" while received < length:\n"
|
||||
" parts.append(sys.stdin.read(length - received))\n"
|
||||
" parts.append(sys.stdin.buffer.read(length - received))\n"
|
||||
" received += len(parts[-1])\n"
|
||||
" data = ''.join(parts)\n"
|
||||
" data = b''.join(parts)\n"
|
||||
" assert len(data) == length\n"
|
||||
" try:\n"
|
||||
" return llsd.parse(data.encode())\n"
|
||||
" return llsd.parse(data)\n"
|
||||
// Seems the old indra.base.llsd module didn't properly
|
||||
// convert IndexError (from running off end of string) to
|
||||
// LLSDParseError.
|
||||
|
|
@ -179,11 +184,11 @@ namespace tut
|
|||
" return _reply\n"
|
||||
"\n"
|
||||
"def put(req):\n"
|
||||
" sys.stdout.write(':'.join((str(len(req)), req)))\n"
|
||||
" sys.stdout.buffer.write(b'%d:%b' % (len(req), req))\n"
|
||||
" sys.stdout.flush()\n"
|
||||
"\n"
|
||||
"def send(pump, data):\n"
|
||||
" put(llsd.format_notation(dict(pump=pump, data=data)).decode())\n"
|
||||
" put(llsd.format_notation(dict(pump=pump, data=data)))\n"
|
||||
"\n"
|
||||
"def request(pump, data):\n"
|
||||
" # we expect 'data' is a dict\n"
|
||||
|
|
|
|||
|
|
@ -46,20 +46,24 @@ typedef U32 uint32_t;
|
|||
|
||||
#include "boost/range.hpp"
|
||||
#include "boost/foreach.hpp"
|
||||
#include "boost/function.hpp"
|
||||
#include "boost/bind.hpp"
|
||||
#include "boost/phoenix/bind/bind_function.hpp"
|
||||
#include "boost/phoenix/core/argument.hpp"
|
||||
using namespace boost::phoenix;
|
||||
|
||||
#include "../llsd.h"
|
||||
#include "../llsdserialize.h"
|
||||
#include "llsd.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llsdutil.h"
|
||||
#include "../llformat.h"
|
||||
#include "llformat.h"
|
||||
#include "llmemorystream.h"
|
||||
|
||||
#include "../test/lltut.h"
|
||||
#include "../test/namedtempfile.h"
|
||||
#include "stringize.h"
|
||||
#include <functional>
|
||||
|
||||
typedef std::function<void(const LLSD& data, std::ostream& str)> FormatterFunction;
|
||||
typedef std::function<bool(std::istream& istr, LLSD& data, llssize max_bytes)> ParserFunction;
|
||||
|
||||
std::vector<U8> string_to_vector(const std::string& str)
|
||||
{
|
||||
|
|
@ -112,7 +116,7 @@ namespace tut
|
|||
mSD = LLUUID::null;
|
||||
expected = "<llsd><uuid /></llsd>\n";
|
||||
xml_test("null uuid", expected);
|
||||
|
||||
|
||||
mSD = LLUUID("c96f9b1e-f589-4100-9774-d98643ce0bed");
|
||||
expected = "<llsd><uuid>c96f9b1e-f589-4100-9774-d98643ce0bed</uuid></llsd>\n";
|
||||
xml_test("uuid", expected);
|
||||
|
|
@ -136,7 +140,7 @@ namespace tut
|
|||
expected = "<llsd><binary encoding=\"base64\">aGVsbG8=</binary></llsd>\n";
|
||||
xml_test("binary", expected);
|
||||
}
|
||||
|
||||
|
||||
template<> template<>
|
||||
void sd_xml_object::test<2>()
|
||||
{
|
||||
|
|
@ -225,7 +229,7 @@ namespace tut
|
|||
expected = "<llsd><map><key>baz</key><undef /><key>foo</key><string>bar</string></map></llsd>\n";
|
||||
xml_test("2 element map", expected);
|
||||
}
|
||||
|
||||
|
||||
template<> template<>
|
||||
void sd_xml_object::test<6>()
|
||||
{
|
||||
|
|
@ -241,7 +245,7 @@ namespace tut
|
|||
expected = "<llsd><binary encoding=\"base64\">Nnw2fGFzZGZoYXBweWJveHw2MGU0NGVjNS0zMDVjLTQzYzItOWExOS1iNGI4OWIxYWUyYTZ8NjBlNDRlYzUtMzA1Yy00M2MyLTlhMTktYjRiODliMWFlMmE2fDYwZTQ0ZWM1LTMwNWMtNDNjMi05YTE5LWI0Yjg5YjFhZTJhNnwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDB8N2ZmZmZmZmZ8N2ZmZmZmZmZ8MHwwfDgyMDAwfDQ1MGZlMzk0LTI5MDQtYzlhZC0yMTRjLWEwN2ViN2ZlZWMyOXwoTm8gRGVzY3JpcHRpb24pfDB8MTB8MA==</binary></llsd>\n";
|
||||
xml_test("binary", expected);
|
||||
}
|
||||
|
||||
|
||||
class TestLLSDSerializeData
|
||||
{
|
||||
public:
|
||||
|
|
@ -250,9 +254,34 @@ namespace tut
|
|||
|
||||
void doRoundTripTests(const std::string&);
|
||||
void checkRoundTrip(const std::string&, const LLSD& v);
|
||||
|
||||
LLPointer<LLSDFormatter> mFormatter;
|
||||
LLPointer<LLSDParser> mParser;
|
||||
|
||||
void setFormatterParser(LLPointer<LLSDFormatter> formatter, LLPointer<LLSDParser> parser)
|
||||
{
|
||||
mFormatter = [formatter](const LLSD& data, std::ostream& str)
|
||||
{
|
||||
formatter->format(data, str);
|
||||
};
|
||||
// this lambda must be mutable since otherwise the bound 'parser'
|
||||
// is assumed to point to a const LLSDParser
|
||||
mParser = [parser](std::istream& istr, LLSD& data, llssize max_bytes) mutable
|
||||
{
|
||||
// reset() call is needed since test code re-uses parser object
|
||||
parser->reset();
|
||||
return (parser->parse(istr, data, max_bytes) > 0);
|
||||
};
|
||||
}
|
||||
|
||||
void setParser(bool (*parser)(LLSD&, std::istream&, llssize))
|
||||
{
|
||||
// why does LLSDSerialize::deserialize() reverse the parse() params??
|
||||
mParser = [parser](std::istream& istr, LLSD& data, llssize max_bytes)
|
||||
{
|
||||
return parser(data, istr, max_bytes);
|
||||
};
|
||||
}
|
||||
|
||||
FormatterFunction mFormatter;
|
||||
ParserFunction mParser;
|
||||
};
|
||||
|
||||
TestLLSDSerializeData::TestLLSDSerializeData()
|
||||
|
|
@ -265,12 +294,11 @@ namespace tut
|
|||
|
||||
void TestLLSDSerializeData::checkRoundTrip(const std::string& msg, const LLSD& v)
|
||||
{
|
||||
std::stringstream stream;
|
||||
mFormatter->format(v, stream);
|
||||
std::stringstream stream;
|
||||
mFormatter(v, stream);
|
||||
//LL_INFOS() << "checkRoundTrip: length " << stream.str().length() << LL_ENDL;
|
||||
LLSD w;
|
||||
mParser->reset(); // reset() call is needed since test code re-uses mParser
|
||||
mParser->parse(stream, w, stream.str().size());
|
||||
mParser(stream, w, stream.str().size());
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -299,52 +327,52 @@ namespace tut
|
|||
fillmap(root[key], width, depth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TestLLSDSerializeData::doRoundTripTests(const std::string& msg)
|
||||
{
|
||||
LLSD v;
|
||||
checkRoundTrip(msg + " undefined", v);
|
||||
|
||||
|
||||
v = true;
|
||||
checkRoundTrip(msg + " true bool", v);
|
||||
|
||||
|
||||
v = false;
|
||||
checkRoundTrip(msg + " false bool", v);
|
||||
|
||||
|
||||
v = 1;
|
||||
checkRoundTrip(msg + " positive int", v);
|
||||
|
||||
|
||||
v = 0;
|
||||
checkRoundTrip(msg + " zero int", v);
|
||||
|
||||
|
||||
v = -1;
|
||||
checkRoundTrip(msg + " negative int", v);
|
||||
|
||||
|
||||
v = 1234.5f;
|
||||
checkRoundTrip(msg + " positive float", v);
|
||||
|
||||
|
||||
v = 0.0f;
|
||||
checkRoundTrip(msg + " zero float", v);
|
||||
|
||||
|
||||
v = -1234.5f;
|
||||
checkRoundTrip(msg + " negative float", v);
|
||||
|
||||
|
||||
// FIXME: need a NaN test
|
||||
|
||||
|
||||
v = LLUUID::null;
|
||||
checkRoundTrip(msg + " null uuid", v);
|
||||
|
||||
|
||||
LLUUID newUUID;
|
||||
newUUID.generate();
|
||||
v = newUUID;
|
||||
checkRoundTrip(msg + " new uuid", v);
|
||||
|
||||
|
||||
v = "";
|
||||
checkRoundTrip(msg + " empty string", v);
|
||||
|
||||
|
||||
v = "some string";
|
||||
checkRoundTrip(msg + " non-empty string", v);
|
||||
|
||||
|
||||
v =
|
||||
"Second Life is a 3-D virtual world entirely built and owned by its residents. "
|
||||
"Since opening to the public in 2003, it has grown explosively and today is "
|
||||
|
|
@ -372,7 +400,7 @@ namespace tut
|
|||
for (U32 block = 0x000000; block <= 0x10ffff; block += block_size)
|
||||
{
|
||||
std::ostringstream out;
|
||||
|
||||
|
||||
for (U32 c = block; c < block + block_size; ++c)
|
||||
{
|
||||
if (c <= 0x000001f
|
||||
|
|
@ -386,7 +414,7 @@ namespace tut
|
|||
if (0x00fdd0 <= c && c <= 0x00fdef) { continue; }
|
||||
if ((c & 0x00fffe) == 0x00fffe) { continue; }
|
||||
// see Unicode standard, section 15.8
|
||||
|
||||
|
||||
if (c <= 0x00007f)
|
||||
{
|
||||
out << (char)(c & 0x7f);
|
||||
|
|
@ -410,55 +438,55 @@ namespace tut
|
|||
out << (char)(0x80 | ((c >> 0) & 0x3f));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
v = out.str();
|
||||
|
||||
std::ostringstream blockmsg;
|
||||
blockmsg << msg << " unicode string block 0x" << std::hex << block;
|
||||
checkRoundTrip(blockmsg.str(), v);
|
||||
}
|
||||
|
||||
|
||||
LLDate epoch;
|
||||
v = epoch;
|
||||
checkRoundTrip(msg + " epoch date", v);
|
||||
|
||||
|
||||
LLDate aDay("2002-12-07T05:07:15.00Z");
|
||||
v = aDay;
|
||||
checkRoundTrip(msg + " date", v);
|
||||
|
||||
|
||||
LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
|
||||
v = path;
|
||||
checkRoundTrip(msg + " url", v);
|
||||
|
||||
|
||||
const char source[] = "it must be a blue moon again";
|
||||
std::vector<U8> data;
|
||||
// note, includes terminating '\0'
|
||||
copy(&source[0], &source[sizeof(source)], back_inserter(data));
|
||||
|
||||
|
||||
v = data;
|
||||
checkRoundTrip(msg + " binary", v);
|
||||
|
||||
|
||||
v = LLSD::emptyMap();
|
||||
checkRoundTrip(msg + " empty map", v);
|
||||
|
||||
|
||||
v = LLSD::emptyMap();
|
||||
v["name"] = "luke"; //v.insert("name", "luke");
|
||||
v["age"] = 3; //v.insert("age", 3);
|
||||
checkRoundTrip(msg + " map", v);
|
||||
|
||||
|
||||
v.clear();
|
||||
v["a"]["1"] = true;
|
||||
v["b"]["0"] = false;
|
||||
checkRoundTrip(msg + " nested maps", v);
|
||||
|
||||
|
||||
v = LLSD::emptyArray();
|
||||
checkRoundTrip(msg + " empty array", v);
|
||||
|
||||
|
||||
v = LLSD::emptyArray();
|
||||
v.append("ali");
|
||||
v.append(28);
|
||||
checkRoundTrip(msg + " array", v);
|
||||
|
||||
|
||||
v.clear();
|
||||
v[0][0] = true;
|
||||
v[1][0] = false;
|
||||
|
|
@ -468,7 +496,7 @@ namespace tut
|
|||
fillmap(v, 10, 3); // 10^6 maps
|
||||
checkRoundTrip(msg + " many nested maps", v);
|
||||
}
|
||||
|
||||
|
||||
typedef tut::test_group<TestLLSDSerializeData> TestLLSDSerializeGroup;
|
||||
typedef TestLLSDSerializeGroup::object TestLLSDSerializeObject;
|
||||
TestLLSDSerializeGroup gTestLLSDSerializeGroup("llsd serialization");
|
||||
|
|
@ -476,35 +504,106 @@ namespace tut
|
|||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<1>()
|
||||
{
|
||||
mFormatter = new LLSDNotationFormatter(false, "", LLSDFormatter::OPTIONS_PRETTY_BINARY);
|
||||
mParser = new LLSDNotationParser();
|
||||
setFormatterParser(new LLSDNotationFormatter(false, "", LLSDFormatter::OPTIONS_PRETTY_BINARY),
|
||||
new LLSDNotationParser());
|
||||
doRoundTripTests("pretty binary notation serialization");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<2>()
|
||||
{
|
||||
mFormatter = new LLSDNotationFormatter(false, "", LLSDFormatter::OPTIONS_NONE);
|
||||
mParser = new LLSDNotationParser();
|
||||
setFormatterParser(new LLSDNotationFormatter(false, "", LLSDFormatter::OPTIONS_NONE),
|
||||
new LLSDNotationParser());
|
||||
doRoundTripTests("raw binary notation serialization");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<3>()
|
||||
{
|
||||
mFormatter = new LLSDXMLFormatter();
|
||||
mParser = new LLSDXMLParser();
|
||||
setFormatterParser(new LLSDXMLFormatter(), new LLSDXMLParser());
|
||||
doRoundTripTests("xml serialization");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<4>()
|
||||
{
|
||||
mFormatter = new LLSDBinaryFormatter();
|
||||
mParser = new LLSDBinaryParser();
|
||||
setFormatterParser(new LLSDBinaryFormatter(), new LLSDBinaryParser());
|
||||
doRoundTripTests("binary serialization");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<5>()
|
||||
{
|
||||
mFormatter = [](const LLSD& sd, std::ostream& str)
|
||||
{
|
||||
LLSDSerialize::serialize(sd, str, LLSDSerialize::LLSD_BINARY);
|
||||
};
|
||||
setParser(LLSDSerialize::deserialize);
|
||||
doRoundTripTests("serialize(LLSD_BINARY)");
|
||||
};
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<6>()
|
||||
{
|
||||
mFormatter = [](const LLSD& sd, std::ostream& str)
|
||||
{
|
||||
LLSDSerialize::serialize(sd, str, LLSDSerialize::LLSD_XML);
|
||||
};
|
||||
setParser(LLSDSerialize::deserialize);
|
||||
doRoundTripTests("serialize(LLSD_XML)");
|
||||
};
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<7>()
|
||||
{
|
||||
mFormatter = [](const LLSD& sd, std::ostream& str)
|
||||
{
|
||||
LLSDSerialize::serialize(sd, str, LLSDSerialize::LLSD_NOTATION);
|
||||
};
|
||||
setParser(LLSDSerialize::deserialize);
|
||||
// In this test, serialize(LLSD_NOTATION) emits a header recognized by
|
||||
// deserialize().
|
||||
doRoundTripTests("serialize(LLSD_NOTATION)");
|
||||
};
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<8>()
|
||||
{
|
||||
setFormatterParser(new LLSDNotationFormatter(false, "", LLSDFormatter::OPTIONS_NONE),
|
||||
new LLSDNotationParser());
|
||||
setParser(LLSDSerialize::deserialize);
|
||||
// This is an interesting test because LLSDNotationFormatter does not
|
||||
// emit an llsd/notation header.
|
||||
doRoundTripTests("LLSDNotationFormatter -> deserialize");
|
||||
};
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<9>()
|
||||
{
|
||||
setFormatterParser(new LLSDXMLFormatter(false, "", LLSDFormatter::OPTIONS_NONE),
|
||||
new LLSDXMLParser());
|
||||
setParser(LLSDSerialize::deserialize);
|
||||
// This is an interesting test because LLSDXMLFormatter does not
|
||||
// emit an LLSD/XML header.
|
||||
doRoundTripTests("LLSDXMLFormatter -> deserialize");
|
||||
};
|
||||
|
||||
/*==========================================================================*|
|
||||
// We do not expect this test to succeed. Without a header, neither
|
||||
// notation LLSD nor binary LLSD reliably start with a distinct character,
|
||||
// the way XML LLSD starts with '<'. By convention, we default to notation
|
||||
// rather than binary.
|
||||
template<> template<>
|
||||
void TestLLSDSerializeObject::test<10>()
|
||||
{
|
||||
setFormatterParser(new LLSDBinaryFormatter(false, "", LLSDFormatter::OPTIONS_NONE),
|
||||
new LLSDBinaryParser());
|
||||
setParser(LLSDSerialize::deserialize);
|
||||
// This is an interesting test because LLSDBinaryFormatter does not
|
||||
// emit an LLSD/Binary header.
|
||||
doRoundTripTests("LLSDBinaryFormatter -> deserialize");
|
||||
};
|
||||
|*==========================================================================*/
|
||||
|
||||
/**
|
||||
* @class TestLLSDParsing
|
||||
|
|
@ -555,7 +654,7 @@ namespace tut
|
|||
public:
|
||||
TestLLSDXMLParsing() {}
|
||||
};
|
||||
|
||||
|
||||
typedef tut::test_group<TestLLSDXMLParsing> TestLLSDXMLParsingGroup;
|
||||
typedef TestLLSDXMLParsingGroup::object TestLLSDXMLParsingObject;
|
||||
TestLLSDXMLParsingGroup gTestLLSDXMLParsingGroup("llsd XML parsing");
|
||||
|
|
@ -586,8 +685,8 @@ namespace tut
|
|||
LLSD(),
|
||||
LLSDParser::PARSE_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDXMLParsingObject::test<2>()
|
||||
{
|
||||
|
|
@ -596,7 +695,7 @@ namespace tut
|
|||
v["amy"] = 23;
|
||||
v["bob"] = LLSD();
|
||||
v["cam"] = 1.23;
|
||||
|
||||
|
||||
ensureParse(
|
||||
"unknown data type",
|
||||
"<llsd><map>"
|
||||
|
|
@ -607,16 +706,16 @@ namespace tut
|
|||
v,
|
||||
v.size() + 1);
|
||||
}
|
||||
|
||||
|
||||
template<> template<>
|
||||
void TestLLSDXMLParsingObject::test<3>()
|
||||
{
|
||||
// test handling of nested bad data
|
||||
|
||||
|
||||
LLSD v;
|
||||
v["amy"] = 23;
|
||||
v["cam"] = 1.23;
|
||||
|
||||
|
||||
ensureParse(
|
||||
"map with html",
|
||||
"<llsd><map>"
|
||||
|
|
@ -626,7 +725,7 @@ namespace tut
|
|||
"</map></llsd>",
|
||||
v,
|
||||
v.size() + 1);
|
||||
|
||||
|
||||
v.clear();
|
||||
v["amy"] = 23;
|
||||
v["cam"] = 1.23;
|
||||
|
|
@ -639,7 +738,7 @@ namespace tut
|
|||
"</map></llsd>",
|
||||
v,
|
||||
v.size() + 1);
|
||||
|
||||
|
||||
v.clear();
|
||||
v["amy"] = 23;
|
||||
v["bob"] = LLSD::emptyMap();
|
||||
|
|
@ -661,7 +760,7 @@ namespace tut
|
|||
v[0] = 23;
|
||||
v[1] = LLSD();
|
||||
v[2] = 1.23;
|
||||
|
||||
|
||||
ensureParse(
|
||||
"array value of html",
|
||||
"<llsd><array>"
|
||||
|
|
@ -671,7 +770,7 @@ namespace tut
|
|||
"</array></llsd>",
|
||||
v,
|
||||
v.size() + 1);
|
||||
|
||||
|
||||
v.clear();
|
||||
v[0] = 23;
|
||||
v[1] = LLSD::emptyMap();
|
||||
|
|
@ -1225,7 +1324,7 @@ namespace tut
|
|||
vec[0] = 'a'; vec[1] = 'b'; vec[2] = 'c';
|
||||
vec[3] = '3'; vec[4] = '2'; vec[5] = '1';
|
||||
LLSD value = vec;
|
||||
|
||||
|
||||
vec.resize(11);
|
||||
vec[0] = 'b'; // for binary
|
||||
vec[5] = 'a'; vec[6] = 'b'; vec[7] = 'c';
|
||||
|
|
@ -1694,85 +1793,83 @@ namespace tut
|
|||
ensureBinaryAndXML("map", test);
|
||||
}
|
||||
|
||||
struct TestPythonCompatible
|
||||
// helper for TestPythonCompatible
|
||||
static std::string import_llsd("import os.path\n"
|
||||
"import sys\n"
|
||||
"try:\n"
|
||||
// new freestanding llsd package
|
||||
" import llsd\n"
|
||||
"except ImportError:\n"
|
||||
// older llbase.llsd module
|
||||
" from llbase import llsd\n");
|
||||
|
||||
// helper for TestPythonCompatible
|
||||
template <typename CONTENT>
|
||||
void python(const std::string& desc, const CONTENT& script, int expect=0)
|
||||
{
|
||||
TestPythonCompatible():
|
||||
// Note the peculiar insertion of __FILE__ into this string. Since
|
||||
// this script is being written into a platform-dependent temp
|
||||
// directory, we can't locate indra/lib/python relative to
|
||||
// Python's __file__. Use __FILE__ instead, navigating relative
|
||||
// to this C++ source file. Use Python raw-string syntax so
|
||||
// Windows pathname backslashes won't mislead Python's string
|
||||
// scanner.
|
||||
import_llsd("import os.path\n"
|
||||
"import sys\n"
|
||||
"from llbase import llsd\n")
|
||||
{}
|
||||
~TestPythonCompatible() {}
|
||||
auto PYTHON(LLStringUtil::getenv("PYTHON"));
|
||||
ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
|
||||
|
||||
std::string import_llsd;
|
||||
|
||||
template <typename CONTENT>
|
||||
void python(const std::string& desc, const CONTENT& script, int expect=0)
|
||||
{
|
||||
auto PYTHON(LLStringUtil::getenv("PYTHON"));
|
||||
ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
|
||||
|
||||
NamedTempFile scriptfile("py", script);
|
||||
NamedTempFile scriptfile("py", script);
|
||||
|
||||
#if LL_WINDOWS
|
||||
std::string q("\"");
|
||||
std::string qPYTHON(q + PYTHON + q);
|
||||
std::string qscript(q + scriptfile.getName() + q);
|
||||
int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(), NULL);
|
||||
if (rc == -1)
|
||||
{
|
||||
char buffer[256];
|
||||
strerror_s(buffer, errno); // C++ can infer the buffer size! :-O
|
||||
ensure(STRINGIZE("Couldn't run Python " << desc << "script: " << buffer), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_equals(STRINGIZE(desc << " script terminated with rc " << rc), rc, expect);
|
||||
}
|
||||
std::string q("\"");
|
||||
std::string qPYTHON(q + PYTHON + q);
|
||||
std::string qscript(q + scriptfile.getName() + q);
|
||||
int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(), NULL);
|
||||
if (rc == -1)
|
||||
{
|
||||
char buffer[256];
|
||||
strerror_s(buffer, errno); // C++ can infer the buffer size! :-O
|
||||
ensure(STRINGIZE("Couldn't run Python " << desc << "script: " << buffer), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_equals(STRINGIZE(desc << " script terminated with rc " << rc), rc, expect);
|
||||
}
|
||||
|
||||
#else // LL_DARWIN, LL_LINUX
|
||||
LLProcess::Params params;
|
||||
params.executable = PYTHON;
|
||||
params.args.add(scriptfile.getName());
|
||||
LLProcessPtr py(LLProcess::create(params));
|
||||
ensure(STRINGIZE("Couldn't launch " << desc << " script"), bool(py));
|
||||
// Implementing timeout would mean messing with alarm() and
|
||||
// catching SIGALRM... later maybe...
|
||||
int status(0);
|
||||
if (waitpid(py->getProcessID(), &status, 0) == -1)
|
||||
LLProcess::Params params;
|
||||
params.executable = PYTHON;
|
||||
params.args.add(scriptfile.getName());
|
||||
LLProcessPtr py(LLProcess::create(params));
|
||||
ensure(STRINGIZE("Couldn't launch " << desc << " script"), bool(py));
|
||||
// Implementing timeout would mean messing with alarm() and
|
||||
// catching SIGALRM... later maybe...
|
||||
int status(0);
|
||||
if (waitpid(py->getProcessID(), &status, 0) == -1)
|
||||
{
|
||||
int waitpid_errno(errno);
|
||||
ensure_equals(STRINGIZE("Couldn't retrieve rc from " << desc << " script: "
|
||||
"waitpid() errno " << waitpid_errno),
|
||||
waitpid_errno, ECHILD);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
int waitpid_errno(errno);
|
||||
ensure_equals(STRINGIZE("Couldn't retrieve rc from " << desc << " script: "
|
||||
"waitpid() errno " << waitpid_errno),
|
||||
waitpid_errno, ECHILD);
|
||||
int rc(WEXITSTATUS(status));
|
||||
ensure_equals(STRINGIZE(desc << " script terminated with rc " << rc),
|
||||
rc, expect);
|
||||
}
|
||||
else if (WIFSIGNALED(status))
|
||||
{
|
||||
ensure(STRINGIZE(desc << " script terminated by signal " << WTERMSIG(status)),
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
int rc(WEXITSTATUS(status));
|
||||
ensure_equals(STRINGIZE(desc << " script terminated with rc " << rc),
|
||||
rc, expect);
|
||||
}
|
||||
else if (WIFSIGNALED(status))
|
||||
{
|
||||
ensure(STRINGIZE(desc << " script terminated by signal " << WTERMSIG(status)),
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure(STRINGIZE(desc << " script produced impossible status " << status),
|
||||
false);
|
||||
}
|
||||
ensure(STRINGIZE(desc << " script produced impossible status " << status),
|
||||
false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct TestPythonCompatible
|
||||
{
|
||||
TestPythonCompatible() {}
|
||||
~TestPythonCompatible() {}
|
||||
};
|
||||
|
||||
typedef tut::test_group<TestPythonCompatible> TestPythonCompatibleGroup;
|
||||
|
|
@ -1798,25 +1895,33 @@ namespace tut
|
|||
"print('Running on', sys.platform)\n");
|
||||
}
|
||||
|
||||
// helper for test<3>
|
||||
static void writeLLSDArray(std::ostream& out, const LLSD& array)
|
||||
// helper for test<3> - test<7>
|
||||
static void writeLLSDArray(const FormatterFunction& serialize,
|
||||
std::ostream& out, const LLSD& array)
|
||||
{
|
||||
BOOST_FOREACH(LLSD item, llsd::inArray(array))
|
||||
for (const LLSD& item : llsd::inArray(array))
|
||||
{
|
||||
LLSDSerialize::toNotation(item, out);
|
||||
// It's important to separate with newlines because Python's llsd
|
||||
// module doesn't support parsing from a file stream, only from a
|
||||
// string, so we have to know how much of the file to read into a
|
||||
// string.
|
||||
out << '\n';
|
||||
// It's important to delimit the entries in this file somehow
|
||||
// because, although Python's llsd.parse() can accept a file
|
||||
// stream, the XML parser expects EOF after a single outer element
|
||||
// -- it doesn't just stop. So we must extract a sequence of bytes
|
||||
// strings from the file. But since one of the serialization
|
||||
// formats we want to test is binary, we can't pick any single
|
||||
// byte value as a delimiter! Use a binary integer length prefix
|
||||
// instead.
|
||||
std::ostringstream buffer;
|
||||
serialize(item, buffer);
|
||||
auto buffstr{ buffer.str() };
|
||||
int bufflen{ static_cast<int>(buffstr.length()) };
|
||||
out.write(reinterpret_cast<const char*>(&bufflen), sizeof(bufflen));
|
||||
out.write(buffstr.c_str(), buffstr.length());
|
||||
}
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<3>()
|
||||
// helper for test<3> - test<7>
|
||||
static void toPythonUsing(const std::string& desc,
|
||||
const FormatterFunction& serialize)
|
||||
{
|
||||
set_test_name("verify sequence to Python");
|
||||
|
||||
LLSD cdata(llsd::array(17, 3.14,
|
||||
"This string\n"
|
||||
"has several\n"
|
||||
|
|
@ -1836,7 +1941,7 @@ namespace tut
|
|||
" except StopIteration:\n"
|
||||
" pass\n"
|
||||
" else:\n"
|
||||
" assert False, 'Too many data items'\n";
|
||||
" raise AssertionError('Too many data items')\n";
|
||||
|
||||
// Create an llsdXXXXXX file containing 'data' serialized to
|
||||
// notation.
|
||||
|
|
@ -1845,32 +1950,128 @@ namespace tut
|
|||
// takes a callable. To this callable it passes the
|
||||
// std::ostream with which it's writing the
|
||||
// NamedTempFile.
|
||||
boost::bind(writeLLSDArray, _1, cdata));
|
||||
[serialize, cdata]
|
||||
(std::ostream& out)
|
||||
{ writeLLSDArray(serialize, out, cdata); });
|
||||
|
||||
python("read C++ notation",
|
||||
python("read C++ " + desc,
|
||||
placeholders::arg1 <<
|
||||
import_llsd <<
|
||||
"def parse_each(iterable):\n"
|
||||
" for item in iterable:\n"
|
||||
" yield llsd.parse(item)\n" <<
|
||||
pydata <<
|
||||
"from functools import partial\n"
|
||||
"import io\n"
|
||||
"import struct\n"
|
||||
"lenformat = struct.Struct('i')\n"
|
||||
"def parse_each(inf):\n"
|
||||
" for rawlen in iter(partial(inf.read, lenformat.size), b''):\n"
|
||||
" len = lenformat.unpack(rawlen)[0]\n"
|
||||
// Since llsd.parse() has no max_bytes argument, instead of
|
||||
// passing the input stream directly to parse(), read the item
|
||||
// into a distinct bytes object and parse that.
|
||||
" data = inf.read(len)\n"
|
||||
" try:\n"
|
||||
" frombytes = llsd.parse(data)\n"
|
||||
" except llsd.LLSDParseError as err:\n"
|
||||
" print(f'*** {err}')\n"
|
||||
" print(f'Bad content:\\n{data!r}')\n"
|
||||
" raise\n"
|
||||
// Also try parsing from a distinct stream.
|
||||
" stream = io.BytesIO(data)\n"
|
||||
" fromstream = llsd.parse(stream)\n"
|
||||
" assert frombytes == fromstream\n"
|
||||
" yield frombytes\n"
|
||||
<< pydata <<
|
||||
// Don't forget raw-string syntax for Windows pathnames.
|
||||
"verify(parse_each(open(r'" << file.getName() << "', 'rb')))\n");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<3>()
|
||||
{
|
||||
set_test_name("to Python using LLSDSerialize::serialize(LLSD_XML)");
|
||||
toPythonUsing("LLSD_XML",
|
||||
[](const LLSD& sd, std::ostream& out)
|
||||
{ LLSDSerialize::serialize(sd, out, LLSDSerialize::LLSD_XML); });
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<4>()
|
||||
{
|
||||
set_test_name("verify sequence from Python");
|
||||
set_test_name("to Python using LLSDSerialize::serialize(LLSD_NOTATION)");
|
||||
toPythonUsing("LLSD_NOTATION",
|
||||
[](const LLSD& sd, std::ostream& out)
|
||||
{ LLSDSerialize::serialize(sd, out, LLSDSerialize::LLSD_NOTATION); });
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<5>()
|
||||
{
|
||||
set_test_name("to Python using LLSDSerialize::serialize(LLSD_BINARY)");
|
||||
toPythonUsing("LLSD_BINARY",
|
||||
[](const LLSD& sd, std::ostream& out)
|
||||
{ LLSDSerialize::serialize(sd, out, LLSDSerialize::LLSD_BINARY); });
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<6>()
|
||||
{
|
||||
set_test_name("to Python using LLSDSerialize::toXML()");
|
||||
toPythonUsing("toXML()", LLSDSerialize::toXML);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<7>()
|
||||
{
|
||||
set_test_name("to Python using LLSDSerialize::toNotation()");
|
||||
toPythonUsing("toNotation()", LLSDSerialize::toNotation);
|
||||
}
|
||||
|
||||
/*==========================================================================*|
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<8>()
|
||||
{
|
||||
set_test_name("to Python using LLSDSerialize::toBinary()");
|
||||
// We don't expect this to work because, without a header,
|
||||
// llsd.parse() will assume notation rather than binary.
|
||||
toPythonUsing("toBinary()", LLSDSerialize::toBinary);
|
||||
}
|
||||
|*==========================================================================*/
|
||||
|
||||
// helper for test<8> - test<12>
|
||||
bool itemFromStream(std::istream& istr, LLSD& item, const ParserFunction& parse)
|
||||
{
|
||||
// reset the output value for debugging clarity
|
||||
item.clear();
|
||||
// We use an int length prefix as a foolproof delimiter even for
|
||||
// binary serialized streams.
|
||||
int length{ 0 };
|
||||
istr.read(reinterpret_cast<char*>(&length), sizeof(length));
|
||||
// return parse(istr, item, length);
|
||||
// Sadly, as of 2022-12-01 it seems we can't really trust our LLSD
|
||||
// parsers to honor max_bytes: this test works better when we read
|
||||
// each item into its own distinct LLMemoryStream, instead of passing
|
||||
// the original istr with a max_bytes constraint.
|
||||
std::vector<U8> buffer(length);
|
||||
istr.read(reinterpret_cast<char*>(buffer.data()), length);
|
||||
LLMemoryStream stream(buffer.data(), length);
|
||||
return parse(stream, item, length);
|
||||
}
|
||||
|
||||
// helper for test<8> - test<12>
|
||||
void fromPythonUsing(const std::string& pyformatter,
|
||||
const ParserFunction& parse=
|
||||
[](std::istream& istr, LLSD& data, llssize max_bytes)
|
||||
{ return LLSDSerialize::deserialize(data, istr, max_bytes); })
|
||||
{
|
||||
// Create an empty data file. This is just a placeholder for our
|
||||
// script to write into. Create it to establish a unique name that
|
||||
// we know.
|
||||
NamedTempFile file("llsd", "");
|
||||
|
||||
python("write Python notation",
|
||||
python("Python " + pyformatter,
|
||||
placeholders::arg1 <<
|
||||
import_llsd <<
|
||||
"import struct\n"
|
||||
"lenformat = struct.Struct('i')\n"
|
||||
"DATA = [\n"
|
||||
" 17,\n"
|
||||
" 3.14,\n"
|
||||
|
|
@ -1881,34 +2082,87 @@ namespace tut
|
|||
"]\n"
|
||||
// Don't forget raw-string syntax for Windows pathnames.
|
||||
// N.B. Using 'print' implicitly adds newlines.
|
||||
"with open(r'" << file.getName() << "', 'w') as f:\n"
|
||||
"with open(r'" << file.getName() << "', 'wb') as f:\n"
|
||||
" for item in DATA:\n"
|
||||
" print(llsd.format_notation(item).decode(), file=f)\n");
|
||||
" serialized = llsd." << pyformatter << "(item)\n"
|
||||
" f.write(lenformat.pack(len(serialized)))\n"
|
||||
" f.write(serialized)\n");
|
||||
|
||||
std::ifstream inf(file.getName().c_str());
|
||||
LLSD item;
|
||||
// Notice that we're not doing anything special to parse out the
|
||||
// newlines: LLSDSerialize::fromNotation ignores them. While it would
|
||||
// seem they're not strictly necessary, going in this direction, we
|
||||
// want to ensure that notation-separated-by-newlines works in both
|
||||
// directions -- since in practice, a given file might be read by
|
||||
// either language.
|
||||
ensure_equals("Failed to read LLSD::Integer from Python",
|
||||
LLSDSerialize::fromNotation(item, inf, LLSDSerialize::SIZE_UNLIMITED),
|
||||
1);
|
||||
ensure_equals(item.asInteger(), 17);
|
||||
ensure_equals("Failed to read LLSD::Real from Python",
|
||||
LLSDSerialize::fromNotation(item, inf, LLSDSerialize::SIZE_UNLIMITED),
|
||||
1);
|
||||
ensure_approximately_equals("Bad LLSD::Real value from Python",
|
||||
item.asReal(), 3.14, 7); // 7 bits ~= 0.01
|
||||
ensure_equals("Failed to read LLSD::String from Python",
|
||||
LLSDSerialize::fromNotation(item, inf, LLSDSerialize::SIZE_UNLIMITED),
|
||||
1);
|
||||
ensure_equals(item.asString(),
|
||||
"This string\n"
|
||||
"has several\n"
|
||||
"lines.");
|
||||
|
||||
try
|
||||
{
|
||||
ensure("Failed to read LLSD::Integer from Python",
|
||||
itemFromStream(inf, item, parse));
|
||||
ensure_equals(item.asInteger(), 17);
|
||||
ensure("Failed to read LLSD::Real from Python",
|
||||
itemFromStream(inf, item, parse));
|
||||
ensure_approximately_equals("Bad LLSD::Real value from Python",
|
||||
item.asReal(), 3.14, 7); // 7 bits ~= 0.01
|
||||
ensure("Failed to read LLSD::String from Python",
|
||||
itemFromStream(inf, item, parse));
|
||||
ensure_equals(item.asString(),
|
||||
"This string\n"
|
||||
"has several\n"
|
||||
"lines.");
|
||||
}
|
||||
catch (const tut::failure& err)
|
||||
{
|
||||
std::cout << "for " << err.what() << ", item = " << item << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<8>()
|
||||
{
|
||||
set_test_name("from Python XML using LLSDSerialize::deserialize()");
|
||||
fromPythonUsing("format_xml");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<9>()
|
||||
{
|
||||
set_test_name("from Python notation using LLSDSerialize::deserialize()");
|
||||
fromPythonUsing("format_notation");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<10>()
|
||||
{
|
||||
set_test_name("from Python binary using LLSDSerialize::deserialize()");
|
||||
fromPythonUsing("format_binary");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<11>()
|
||||
{
|
||||
set_test_name("from Python XML using fromXML()");
|
||||
// fromXML()'s optional 3rd param isn't max_bytes, it's emit_errors
|
||||
fromPythonUsing("format_xml",
|
||||
[](std::istream& istr, LLSD& data, llssize)
|
||||
{ return LLSDSerialize::fromXML(data, istr) > 0; });
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<12>()
|
||||
{
|
||||
set_test_name("from Python notation using fromNotation()");
|
||||
fromPythonUsing("format_notation",
|
||||
[](std::istream& istr, LLSD& data, llssize max_bytes)
|
||||
{ return LLSDSerialize::fromNotation(data, istr, max_bytes) > 0; });
|
||||
}
|
||||
|
||||
/*==========================================================================*|
|
||||
template<> template<>
|
||||
void TestPythonCompatibleObject::test<13>()
|
||||
{
|
||||
set_test_name("from Python binary using fromBinary()");
|
||||
// We don't expect this to work because format_binary() emits a
|
||||
// header, but fromBinary() won't recognize a header.
|
||||
fromPythonUsing("format_binary",
|
||||
[](std::istream& istr, LLSD& data, llssize max_bytes)
|
||||
{ return LLSDSerialize::fromBinary(data, istr, max_bytes) > 0; });
|
||||
}
|
||||
|*==========================================================================*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ from io import StringIO
|
|||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
|
||||
|
||||
from llbase import llsd
|
||||
import llsd
|
||||
|
||||
# we're in llcorehttp/tests ; testrunner.py is found in llmessage/tests
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
|
||||
|
|
|
|||
|
|
@ -1336,5 +1336,47 @@ void HttpCoroutineAdapter::trivialPostCoro(std::string url, LLCore::HttpRequest:
|
|||
}
|
||||
|
||||
|
||||
/*static*/
|
||||
void HttpCoroutineAdapter::callbackHttpDel(const std::string &url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success,
|
||||
completionCallback_t failure)
|
||||
{
|
||||
LLCoros::instance().launch("HttpCoroutineAdapter::genericDelCoro",
|
||||
boost::bind(&HttpCoroutineAdapter::trivialDelCoro, url, policyId, success, failure));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void HttpCoroutineAdapter::trivialDelCoro(std::string url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success,
|
||||
completionCallback_t failure)
|
||||
{
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericDelCoro", policyId));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
|
||||
|
||||
httpOpts->setWantHeaders(true);
|
||||
|
||||
LL_INFOS("HttpCoroutineAdapter", "genericDelCoro") << "Generic DEL for " << url << LL_ENDL;
|
||||
|
||||
LLSD result = httpAdapter->deleteAndSuspend(httpRequest, url, httpOpts);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
if (failure)
|
||||
{
|
||||
failure(httpResults);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
success(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end namespace LLCoreHttpUtil
|
||||
|
|
|
|||
|
|
@ -608,6 +608,9 @@ public:
|
|||
callbackHttpPost(url, LLCore::HttpRequest::DEFAULT_POLICY_ID, postData, success, failure);
|
||||
}
|
||||
|
||||
static void callbackHttpDel(const std::string &url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success = NULL,
|
||||
completionCallback_t failure = NULL);
|
||||
|
||||
/// Generic Get and post routines for HTTP via coroutines.
|
||||
/// These static methods do all required setup for the GET or POST operation.
|
||||
/// When the operation completes successfully they will put the success message in the log at INFO level,
|
||||
|
|
@ -669,6 +672,7 @@ private:
|
|||
|
||||
static void trivialGetCoro(std::string url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success, completionCallback_t failure);
|
||||
static void trivialPostCoro(std::string url, LLCore::HttpRequest::policy_t policyId, LLSD postData, completionCallback_t success, completionCallback_t failure);
|
||||
static void trivialDelCoro(std::string url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success, completionCallback_t failure);
|
||||
|
||||
void checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers);
|
||||
|
||||
|
|
|
|||
|
|
@ -171,8 +171,11 @@ 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
|
||||
const S32 ESTATE_MAX_MANAGERS = 20;
|
||||
const S32 ESTATE_MAX_MANAGERS_OS = 15; // <FS:Ansariel> OpenSim
|
||||
const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access
|
||||
const S32 ESTATE_MAX_BANNED_IDS = 750; // max for banned
|
||||
const S32 ESTATE_MAX_BANNED_IDS_OS = 500; // max for banned // <FS:Ansariel> OpenSim
|
||||
const S32 ESTATE_MAX_GROUP_IDS = (S32) ESTATE_ACCESS_MAX_ENTRIES_PER_PACKET;
|
||||
|
||||
// 'Sim Wide Delete' flags
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ import os
|
|||
import sys
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
|
||||
from llbase.fastest_elementtree import parse as xml_parse
|
||||
from llbase import llsd
|
||||
from llsd.fastest_elementtree import parse as xml_parse
|
||||
import llsd
|
||||
from testrunner import freeport, run, debug, VERBOSE
|
||||
import time
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,14 @@ public:
|
|||
|
||||
static const LLMaterialID null;
|
||||
|
||||
// Returns a 64 bits digest of the material Id, by XORing its two 64 bits
|
||||
// long words. HB
|
||||
inline U64 getDigest64() const
|
||||
{
|
||||
U64* tmp = (U64*)mID;
|
||||
return tmp[0] ^ tmp[1];
|
||||
}
|
||||
|
||||
private:
|
||||
void parseFromBinary(const LLSD::Binary& pMaterialID);
|
||||
void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
|
||||
|
|
@ -74,5 +82,23 @@ private:
|
|||
U8 mID[MATERIAL_ID_SIZE];
|
||||
} ;
|
||||
|
||||
// std::hash implementation for LLMaterialID
|
||||
namespace std
|
||||
{
|
||||
template<> struct hash<LLMaterialID>
|
||||
{
|
||||
inline size_t operator()(const LLMaterialID& id) const noexcept
|
||||
{
|
||||
return (size_t)id.getDigest64();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// For use with boost containers.
|
||||
inline size_t hash_value(const LLMaterialID& id) noexcept
|
||||
{
|
||||
return (size_t)id.getDigest64();
|
||||
}
|
||||
|
||||
#endif // LL_LLMATERIALID_H
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ LLDragHandle::LLDragHandle(const LLDragHandle::Params& p)
|
|||
|
||||
LLDragHandle::~LLDragHandle()
|
||||
{
|
||||
gFocusMgr.removeKeyboardFocusWithoutCallback(this);
|
||||
removeChild(mTitleBox);
|
||||
delete mTitleBox;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
|
|||
LLFolderViewItem::~LLFolderViewItem()
|
||||
{
|
||||
mViewModelItem = NULL;
|
||||
gFocusMgr.removeKeyboardFocusWithoutCallback(this);
|
||||
}
|
||||
|
||||
BOOL LLFolderViewItem::postBuild()
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ LLLayoutPanel::~LLLayoutPanel()
|
|||
// probably not necessary, but...
|
||||
delete mResizeBar;
|
||||
mResizeBar = NULL;
|
||||
|
||||
gFocusMgr.removeKeyboardFocusWithoutCallback(this);
|
||||
}
|
||||
|
||||
F32 LLLayoutPanel::getAutoResizeFactor() const
|
||||
|
|
|
|||
|
|
@ -70,6 +70,11 @@ LLResizeHandle::LLResizeHandle(const LLResizeHandle::Params& p)
|
|||
}
|
||||
}
|
||||
|
||||
LLResizeHandle::~LLResizeHandle()
|
||||
{
|
||||
gFocusMgr.removeKeyboardFocusWithoutCallback(this);
|
||||
}
|
||||
|
||||
|
||||
BOOL LLResizeHandle::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public:
|
|||
Params();
|
||||
};
|
||||
|
||||
~LLResizeHandle();
|
||||
protected:
|
||||
LLResizeHandle(const LLResizeHandle::Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
|
|
|
|||
|
|
@ -908,6 +908,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
|
|||
continue;
|
||||
}
|
||||
|
||||
// Got an item. Load it up.
|
||||
// If not declared, assume it's a string
|
||||
if (!declared)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6.6.14
|
||||
6.6.15
|
||||
|
|
|
|||
|
|
@ -240,6 +240,12 @@
|
|||
<string>NoAudio</string>
|
||||
</map>
|
||||
|
||||
<key>nofmod</key>
|
||||
<map>
|
||||
<key>map-to</key>
|
||||
<string>UseMediaPluginsForStreamingAudio</string>
|
||||
</map>
|
||||
|
||||
<key>noninteractive</key>
|
||||
<map>
|
||||
<key>desc</key>
|
||||
|
|
|
|||
|
|
@ -9904,6 +9904,17 @@
|
|||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>UseMediaPluginsForStreamingAudio</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use media plugins (VLC) for streaming audio.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>NoHardwareProbe</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -14555,11 +14566,11 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>ShowBanLines</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show in-world ban/access borders</string>
|
||||
<string>Show in-world ban/access borders, 0 - do not show, 1 - show on collision, 2 - show on proximity</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
|
|
@ -22265,17 +22276,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>360CaptureUseInterestListCap</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Flag if set, uses the new InterestList cap to ask the simulator for full content</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>360CaptureJPEGEncodeQuality</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -23680,6 +23680,39 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>StatsReportMaxDuration</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum seconds for viewer stats file data, prevents huge file</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>300</real>
|
||||
</map>
|
||||
<key>StatsReportFileInterval</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Interval to save viewer stats file data</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.2</real>
|
||||
</map>
|
||||
<key>StatsReportSkipZeroDataSaves</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>In viewer stats data file, skip saving entry if there is no data</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSNetMapPhantomOpacity</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -26405,5 +26438,16 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSSortAttachmentSpotsAlphabetically</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Sorts the attachment spots in the "Attach to" menus alphabetically</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
|
|||
|
|
@ -174,11 +174,6 @@ FSAreaSearch::FSAreaSearch(const LLSD& key) :
|
|||
mRlvBehaviorCallbackConnection()
|
||||
{
|
||||
LLViewerRegion::sFSAreaSearchActive = true;
|
||||
if( LLViewerRegion* region = gAgent.getRegion() )
|
||||
{
|
||||
checkRegion();
|
||||
}
|
||||
|
||||
mFactoryMap["area_search_list_panel"] = LLCallbackMap(createPanelList, this);
|
||||
mFactoryMap["area_search_find_panel"] = LLCallbackMap(createPanelFind, this);
|
||||
mFactoryMap["area_search_filter_panel"] = LLCallbackMap(createPanelFilter, this);
|
||||
|
|
@ -190,24 +185,11 @@ FSAreaSearch::FSAreaSearch(const LLSD& key) :
|
|||
|
||||
mParcelChangedObserver = std::make_unique<FSParcelChangeObserver>(this);
|
||||
LLViewerParcelMgr::getInstance()->addObserver(mParcelChangedObserver.get());
|
||||
mRegionChangeConnection = gAgent.addRegionChangedCallback(boost::bind(&FSAreaSearch::checkRegion, this));
|
||||
}
|
||||
|
||||
FSAreaSearch::~FSAreaSearch()
|
||||
{
|
||||
LLViewerRegion::sFSAreaSearchActive = false;
|
||||
|
||||
// Tell the Simulator not to send us everything anymore
|
||||
// and revert to the regular "keyhole" frustum of interest
|
||||
// list updates.
|
||||
if( !LLApp::isExiting() )
|
||||
{
|
||||
if( LLViewerRegion* region = gAgent.getRegion() )
|
||||
{
|
||||
region->useFullUpdateInterestListMode(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gIdleCallbacks.deleteFunction(idle, this))
|
||||
{
|
||||
LL_WARNS("FSAreaSearch") << "FSAreaSearch::~FSAreaSearch() failed to delete callback" << LL_ENDL;
|
||||
|
|
@ -232,11 +214,6 @@ FSAreaSearch::~FSAreaSearch()
|
|||
LLViewerParcelMgr::getInstance()->removeObserver(mParcelChangedObserver.get());
|
||||
mParcelChangedObserver = nullptr;
|
||||
}
|
||||
|
||||
if (mRegionChangeConnection.connected())
|
||||
{
|
||||
mRegionChangeConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL FSAreaSearch::postBuild()
|
||||
|
|
@ -343,28 +320,24 @@ void FSAreaSearch::updateRlvRestrictions(ERlvBehaviour behavior)
|
|||
|
||||
void FSAreaSearch::checkRegion()
|
||||
{
|
||||
static LLUUID last_region_id = LLUUID::null;
|
||||
auto last_region = LLWorld::instance().getRegionFromID(last_region_id);
|
||||
// Check if we changed region, if so reset the interest list to full,
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if( region && (region != last_region) )
|
||||
{
|
||||
region->useFullUpdateInterestListMode(true, true); // we force this because we want a true count
|
||||
if ( mActive )
|
||||
if (mActive)
|
||||
{
|
||||
// Check if we changed region, and if we did, clear the object details cache.
|
||||
if (LLViewerRegion* region = gAgent.getRegion(); region && (region != mLastRegion))
|
||||
{
|
||||
// and if we did and are active, clear the object details cache.
|
||||
if( !mExcludeNeighborRegions )
|
||||
if (!mExcludeNeighborRegions)
|
||||
{
|
||||
std::vector<LLViewerRegion*> uniqueRegions;
|
||||
region->getNeighboringRegions(uniqueRegions);
|
||||
if( std::find( uniqueRegions.begin(), uniqueRegions.end(), last_region ) != uniqueRegions.end() )
|
||||
if (std::find(uniqueRegions.begin(), uniqueRegions.end(), mLastRegion) != uniqueRegions.end())
|
||||
{
|
||||
// Crossed into a neighboring region, no need to clear everything.
|
||||
last_region_id = region->getRegionID();
|
||||
mLastRegion = region;
|
||||
return;
|
||||
}
|
||||
// else teleported into a new region
|
||||
}
|
||||
mLastRegion = region;
|
||||
mRequested = 0;
|
||||
mObjectDetails.clear();
|
||||
mRegionRequests.clear();
|
||||
|
|
@ -374,14 +347,7 @@ void FSAreaSearch::checkRegion()
|
|||
mPanelList->setAgentLastPosition(gAgent.getPositionGlobal());
|
||||
mRefresh = true;
|
||||
}
|
||||
if( last_region )
|
||||
{
|
||||
// we clear the old region status, because the instance may persist for us
|
||||
// but the region itself will have reset when we left.
|
||||
last_region->clearFullUpdateInterestList();
|
||||
}
|
||||
}
|
||||
last_region_id = region->getRegionID();
|
||||
}
|
||||
|
||||
void FSAreaSearch::refreshList(bool cache_clear)
|
||||
|
|
|
|||
|
|
@ -213,8 +213,7 @@ private:
|
|||
typedef std::map<LLUUID, boost::signals2::connection> name_cache_connection_map_t;
|
||||
name_cache_connection_map_t mNameCacheConnections;
|
||||
|
||||
boost::signals2::connection mRegionChangeConnection; // reset interest list verbosity after TP
|
||||
|
||||
LLViewerRegion* mLastRegion;
|
||||
|
||||
class FSParcelChangeObserver;
|
||||
friend class FSParcelChangeObserver;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ public:
|
|||
// requests will be throttled from a non-trusted browser
|
||||
LLObjectIMHandler() : LLCommandHandler("objectim", UNTRUSTED_THROTTLE) {}
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (params.size() < 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
FSFloaterPoseStand::FSFloaterPoseStand(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mComboPose(NULL),
|
||||
mComboPose(nullptr),
|
||||
mPoseStandLock(false),
|
||||
mAOPaused(false)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
FSFloaterRadar::FSFloaterRadar(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mRadarPanel(NULL)
|
||||
mRadarPanel(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,8 +135,7 @@ BOOL FSFloaterWearableFavorites::postBuild()
|
|||
|
||||
mOptionsButton = getChild<LLMenuButton>("options_btn");
|
||||
|
||||
LLToggleableMenu* options_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_fs_wearable_favorites.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
if (options_menu)
|
||||
if (LLToggleableMenu* options_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_fs_wearable_favorites.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); options_menu)
|
||||
{
|
||||
mOptionsMenuHandle = options_menu->getHandle();
|
||||
mOptionsButton->setMenu(options_menu, LLMenuButton::MP_BOTTOM_LEFT);
|
||||
|
|
@ -204,8 +203,7 @@ BOOL FSFloaterWearableFavorites::handleKeyHere(KEY key, MASK mask)
|
|||
// static
|
||||
std::optional<LLUUID> FSFloaterWearableFavorites::getWearableFavoritesFolderID()
|
||||
{
|
||||
LLUUID fs_root_cat_id = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER);
|
||||
if (!fs_root_cat_id.isNull())
|
||||
if (LLUUID fs_root_cat_id = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); !fs_root_cat_id.isNull())
|
||||
{
|
||||
LLInventoryModel::item_array_t* items;
|
||||
LLInventoryModel::cat_array_t* cats;
|
||||
|
|
@ -339,8 +337,7 @@ bool FSFloaterWearableFavorites::onOptionsMenuItemChecked(const LLSD& userdata)
|
|||
|
||||
void FSFloaterWearableFavorites::onDoubleClick()
|
||||
{
|
||||
LLUUID selected_item_id = mItemsList->getSelectedUUID();
|
||||
if (selected_item_id.notNull())
|
||||
if (LLUUID selected_item_id = mItemsList->getSelectedUUID(); selected_item_id.notNull())
|
||||
{
|
||||
uuid_vec_t ids;
|
||||
ids.push_back(selected_item_id);
|
||||
|
|
|
|||
|
|
@ -1437,7 +1437,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (params.size() < 2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -120,9 +120,9 @@ bool FSKeywords::chatContainsKeyword(const LLChat& chat, bool is_local)
|
|||
|
||||
if (sFSKeywordMatchWholeWords)
|
||||
{
|
||||
for (std::vector<std::string>::iterator it = mWordList.begin(); it != mWordList.end(); ++it)
|
||||
for (const auto& word : mWordList)
|
||||
{
|
||||
if (boost::regex_search(source, boost::regex("\\b" + (*it) + "\\b")))
|
||||
if (boost::regex_search(source, boost::regex("\\b" + word + "\\b")))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -130,9 +130,9 @@ bool FSKeywords::chatContainsKeyword(const LLChat& chat, bool is_local)
|
|||
}
|
||||
else
|
||||
{
|
||||
for (std::vector<std::string>::iterator it = mWordList.begin(); it != mWordList.end(); ++it)
|
||||
for (const auto& word : mWordList)
|
||||
{
|
||||
if (source.find((*it)) != std::string::npos)
|
||||
if (source.find(word) != std::string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -145,30 +145,27 @@ bool FSKeywords::chatContainsKeyword(const LLChat& chat, bool is_local)
|
|||
// <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground
|
||||
void FSKeywords::notify(const LLChat& chat)
|
||||
{
|
||||
if (chat.mFromID != gAgentID || chat.mFromName == SYSTEM_FROM)
|
||||
if ((chat.mFromID != gAgentID || chat.mFromName == SYSTEM_FROM) && !chat.mMuted && !LLMuteList::getInstance()->isMuted(chat.mFromID))
|
||||
{
|
||||
if (!chat.mMuted && !LLMuteList::getInstance()->isMuted(chat.mFromID))
|
||||
static LLCachedControl<bool> PlayModeUISndFSKeywordSound(gSavedPerAccountSettings, "PlayModeUISndFSKeywordSound");
|
||||
if (PlayModeUISndFSKeywordSound)
|
||||
{
|
||||
static LLCachedControl<bool> PlayModeUISndFSKeywordSound(gSavedPerAccountSettings, "PlayModeUISndFSKeywordSound");
|
||||
if (PlayModeUISndFSKeywordSound)
|
||||
{
|
||||
LLUI::getInstance()->mAudioCallback(LLUUID(gSavedPerAccountSettings.getString("UISndFSKeywordSound")));
|
||||
}
|
||||
LLUI::getInstance()->mAudioCallback(LLUUID(gSavedPerAccountSettings.getString("UISndFSKeywordSound")));
|
||||
}
|
||||
|
||||
static LLCachedControl<bool> FSEnableGrowl(gSavedSettings, "FSEnableGrowl");
|
||||
if (FSEnableGrowl)
|
||||
static LLCachedControl<bool> FSEnableGrowl(gSavedSettings, "FSEnableGrowl");
|
||||
if (FSEnableGrowl)
|
||||
{
|
||||
std::string msg = chat.mFromName;
|
||||
if (is_irc_me_prefix(chat.mText))
|
||||
{
|
||||
std::string msg = chat.mFromName;
|
||||
if (is_irc_me_prefix(chat.mText))
|
||||
{
|
||||
msg = msg + chat.mText.substr(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = msg + ": " + chat.mText;
|
||||
}
|
||||
GrowlManager::notify("Keyword Alert", msg, GROWL_KEYWORD_ALERT_TYPE);
|
||||
msg = msg + chat.mText.substr(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = msg + ": " + chat.mText;
|
||||
}
|
||||
GrowlManager::notify("Keyword Alert", msg, GROWL_KEYWORD_ALERT_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,16 +148,13 @@ void FSMoneyTrackerListMenu::onContextMenuItemClick(const LLSD& userdata)
|
|||
|
||||
if (option == "copy")
|
||||
{
|
||||
FSMoneyTracker* floater = LLFloaterReg::findTypedInstance<FSMoneyTracker>("money_tracker");
|
||||
if (floater)
|
||||
if (FSMoneyTracker* floater = LLFloaterReg::findTypedInstance<FSMoneyTracker>("money_tracker"); floater)
|
||||
{
|
||||
std::string copy_text;
|
||||
LLNameListCtrl* list = floater->getChild<LLNameListCtrl>("payment_list");
|
||||
|
||||
std::vector<LLScrollListItem*> selected = list->getAllSelected();
|
||||
for (std::vector<LLScrollListItem*>::iterator it = selected.begin(); it != selected.end(); ++it)
|
||||
for (auto item : list->getAllSelected())
|
||||
{
|
||||
const LLScrollListItem* item = *it;
|
||||
copy_text += ( (copy_text.empty() ? "" : "\n")
|
||||
+ item->getColumn(0)->getValue().asString() + ";"
|
||||
+ item->getColumn(1)->getValue().asString() + ";"
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@
|
|||
#include "rlvactions.h"
|
||||
#include "rlvhandler.h"
|
||||
|
||||
static const U32 NAME_PREDICTION_MINIMUM_LENGTH = 3;
|
||||
constexpr U32 NAME_PREDICTION_MINIMUM_LENGTH = 3;
|
||||
|
||||
// *HACK* chat bar cannot return its correct height for some reason
|
||||
static const S32 MAGIC_CHAT_BAR_PAD = 5;
|
||||
constexpr S32 MAGIC_CHAT_BAR_PAD = 5;
|
||||
|
||||
struct LLChatTypeTrigger {
|
||||
std::string name;
|
||||
|
|
@ -237,8 +237,8 @@ bool matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
|
|||
S32 FSNearbyChat::sLastSpecialChatChannel = 0;
|
||||
|
||||
FSNearbyChat::FSNearbyChat() :
|
||||
mDefaultChatBar(NULL),
|
||||
mFocusedInputEditor(NULL)
|
||||
mDefaultChatBar(nullptr),
|
||||
mFocusedInputEditor(nullptr)
|
||||
{
|
||||
gSavedSettings.getControl("MainChatbarVisible")->getSignal()->connect(boost::bind(&FSNearbyChat::onDefaultChatBarButtonClicked, this));
|
||||
}
|
||||
|
|
@ -847,7 +847,7 @@ public:
|
|||
LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_THROTTLE) { }
|
||||
|
||||
// Your code here
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map,
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
bool retval = false;
|
||||
|
|
|
|||
|
|
@ -132,12 +132,11 @@ BOOL FSPanelBlockList::handleKeyHere(KEY key, MASK mask)
|
|||
void FSPanelBlockList::selectBlocked(const LLUUID& mute_id)
|
||||
{
|
||||
mBlockedList->deselectAllItems();
|
||||
std::vector<LLScrollListItem*> items = mBlockedList->getAllData();
|
||||
for (std::vector<LLScrollListItem*>::iterator it = items.begin(); it != items.end(); it++)
|
||||
for (auto item : mBlockedList->getAllData())
|
||||
{
|
||||
if ((*it)->getColumn(3)->getValue().asUUID() == mute_id)
|
||||
if (item->getColumn(3)->getValue().asUUID() == mute_id)
|
||||
{
|
||||
(*it)->setSelected(TRUE);
|
||||
item->setSelected(TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -171,17 +170,15 @@ void FSPanelBlockList::refreshBlockedList()
|
|||
{
|
||||
mBlockedList->deleteAllItems();
|
||||
|
||||
std::vector<LLMute> mutes = LLMuteList::getInstance()->getMutes();
|
||||
std::vector<LLMute>::iterator it;
|
||||
for (it = mutes.begin(); it != mutes.end(); ++it)
|
||||
for (const auto& mute : LLMuteList::getInstance()->getMutes())
|
||||
{
|
||||
LLScrollListItem::Params item_p;
|
||||
item_p.enabled(TRUE);
|
||||
item_p.enabled(true);
|
||||
item_p.value(LLUUID::generateNewID()); // can't link UUID of blocked item directly because of mutes by name
|
||||
item_p.columns.add().column("item_name").value(it->mName);
|
||||
item_p.columns.add().column("item_type").value(it->getDisplayType());
|
||||
item_p.columns.add().column("item_mute_type").value(it->mType);
|
||||
item_p.columns.add().column("item_mute_uuid").value(it->mID);
|
||||
item_p.columns.add().column("item_name").value(mute.mName);
|
||||
item_p.columns.add().column("item_type").value(mute.getDisplayType());
|
||||
item_p.columns.add().column("item_mute_type").value(mute.mType);
|
||||
item_p.columns.add().column("item_mute_uuid").value(mute.mID);
|
||||
|
||||
mBlockedList->addRow(item_p, ADD_BOTTOM);
|
||||
}
|
||||
|
|
@ -208,11 +205,10 @@ void FSPanelBlockList::removeMutes()
|
|||
// list after each removal, sending us straight into a crash!
|
||||
LLMuteList::getInstance()->removeObserver(this);
|
||||
|
||||
std::vector<LLScrollListItem*> selected_items = mBlockedList->getAllSelected();
|
||||
for (std::vector<LLScrollListItem*>::iterator it = selected_items.begin(); it != selected_items.end(); it++)
|
||||
for (auto item : mBlockedList->getAllSelected())
|
||||
{
|
||||
std::string name = (*it)->getColumn(COL_NAME)->getValue().asString();
|
||||
LLUUID id = (*it)->getColumn(COL_UUID)->getValue().asUUID();
|
||||
std::string name = item->getColumn(COL_NAME)->getValue().asString();
|
||||
LLUUID id = item->getColumn(COL_UUID)->getValue().asUUID();
|
||||
LLMute mute(id, name);
|
||||
LLMuteList::getInstance()->remove(mute);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ class LLLoginLocationAutoHandler : public LLCommandHandler
|
|||
public:
|
||||
// don't allow from external browsers
|
||||
LLLoginLocationAutoHandler() : LLCommandHandler("location_login", UNTRUSTED_BLOCK) { }
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ FSPanelRadar::FSPanelRadar()
|
|||
mFSRadarColumnConfigConnection(),
|
||||
mLastResizeDelta(0)
|
||||
{
|
||||
mButtonsUpdater = new FSButtonsUpdater(boost::bind(&FSPanelRadar::updateButtons, this));
|
||||
mButtonsUpdater = std::make_unique<FSButtonsUpdater>(boost::bind(&FSPanelRadar::updateButtons, this));
|
||||
mCommitCallbackRegistrar.add("Radar.AddFriend", boost::bind(&FSPanelRadar::onAddFriendButtonClicked, this));
|
||||
mCommitCallbackRegistrar.add("Radar.Gear", boost::bind(&FSPanelRadar::onGearButtonClicked, this, _1));
|
||||
|
||||
|
|
@ -117,9 +117,8 @@ FSPanelRadar::~FSPanelRadar()
|
|||
mFSRadarColumnConfigConnection.disconnect();
|
||||
}
|
||||
|
||||
delete mButtonsUpdater;
|
||||
|
||||
if (mOptionsMenuHandle.get()) mOptionsMenuHandle.get()->die();
|
||||
if (mOptionsMenuHandle.get())
|
||||
mOptionsMenuHandle.get()->die();
|
||||
}
|
||||
|
||||
BOOL FSPanelRadar::postBuild()
|
||||
|
|
@ -152,8 +151,7 @@ BOOL FSPanelRadar::postBuild()
|
|||
mRadarGearButton = getChild<LLButton>("gear_btn");
|
||||
mOptionsButton = getChild<LLMenuButton>("options_btn");
|
||||
|
||||
LLToggleableMenu* options_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_fs_radar_options.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
if (options_menu)
|
||||
if (LLToggleableMenu* options_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_fs_radar_options.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); options_menu)
|
||||
{
|
||||
mOptionsMenuHandle = options_menu->getHandle();
|
||||
mOptionsButton->setMenu(options_menu, LLMenuButton::MP_BOTTOM_LEFT);
|
||||
|
|
@ -204,8 +202,7 @@ void FSPanelRadar::updateButtons()
|
|||
|
||||
LLUUID FSPanelRadar::getCurrentItemID() const
|
||||
{
|
||||
LLScrollListItem* item = mRadarList->getFirstSelected();
|
||||
if (item)
|
||||
if (LLScrollListItem* item = mRadarList->getFirstSelected(); item)
|
||||
{
|
||||
return item->getUUID();
|
||||
}
|
||||
|
|
@ -251,21 +248,14 @@ void FSPanelRadar::onRadarListDoubleClicked()
|
|||
LLUUID clicked_id = item->getUUID();
|
||||
std::string name = item->getColumn(mRadarList->getColumn("name")->mIndex)->getValue().asString();
|
||||
|
||||
FSRadar* radar = FSRadar::getInstance();
|
||||
if (radar)
|
||||
{
|
||||
radar->zoomAvatar(clicked_id, name);
|
||||
}
|
||||
FSRadar::getInstance()->zoomAvatar(clicked_id, name);
|
||||
}
|
||||
|
||||
void FSPanelRadar::onRadarListCommitted()
|
||||
{
|
||||
uuid_vec_t selected_uuids;
|
||||
LLUUID sVal = mRadarList->getSelectedValue().asUUID();
|
||||
if (sVal.notNull())
|
||||
if (LLUUID sVal = mRadarList->getSelectedValue().asUUID(); sVal.notNull())
|
||||
{
|
||||
selected_uuids.push_back(sVal);
|
||||
mMiniMap->setSelected(selected_uuids);
|
||||
mMiniMap->setSelected({ sVal });
|
||||
}
|
||||
|
||||
updateButtons();
|
||||
|
|
@ -274,8 +264,7 @@ void FSPanelRadar::onRadarListCommitted()
|
|||
|
||||
void FSPanelRadar::onAddFriendButtonClicked()
|
||||
{
|
||||
LLUUID id = getCurrentItemID();
|
||||
if (id.notNull())
|
||||
if (LLUUID id = getCurrentItemID(); id.notNull())
|
||||
{
|
||||
LLAvatarActions::requestFriendshipDialog(id);
|
||||
}
|
||||
|
|
@ -301,14 +290,10 @@ void FSPanelRadar::onGearButtonClicked(LLUICtrl* btn)
|
|||
|
||||
void FSPanelRadar::requestUpdate()
|
||||
{
|
||||
FSRadar* radar = FSRadar::getInstance();
|
||||
if (radar)
|
||||
{
|
||||
std::vector<LLSD> entries;
|
||||
LLSD stats;
|
||||
radar->getCurrentData(entries, stats);
|
||||
updateList(entries, stats);
|
||||
}
|
||||
std::vector<LLSD> entries;
|
||||
LLSD stats;
|
||||
FSRadar::getInstance()->getCurrentData(entries, stats);
|
||||
updateList(entries, stats);
|
||||
}
|
||||
|
||||
void FSPanelRadar::updateList(const std::vector<LLSD>& entries, const LLSD& stats)
|
||||
|
|
@ -422,21 +407,21 @@ void FSPanelRadar::updateList(const std::vector<LLSD>& entries, const LLSD& stat
|
|||
radarNameCell->setColor(LLColor4(options["name_color"]));
|
||||
}
|
||||
|
||||
LLScrollListText* voiceLevelCell = (LLScrollListText*)row->getColumn(voiceLevelColumnIndex);
|
||||
if (entry.has("voice_level_icon"))
|
||||
{
|
||||
LLScrollListText* voiceLevelCell = (LLScrollListText*)row->getColumn(voiceLevelColumnIndex);
|
||||
voiceLevelCell->setValue(entry["voice_level_icon"].asString());
|
||||
}
|
||||
|
||||
LLScrollListText* flagsCell = (LLScrollListText*)row->getColumn(flagsColumnIndex);
|
||||
if (entry.has("flags"))
|
||||
{
|
||||
LLScrollListText* flagsCell = (LLScrollListText*)row->getColumn(flagsColumnIndex);
|
||||
flagsCell->setValue(flagsColumnValues[entry["flags"].asInteger()]);
|
||||
}
|
||||
|
||||
LLScrollListText* ageCell = (LLScrollListText*)row->getColumn(ageColumnIndex);
|
||||
if (options.has("age_color"))
|
||||
{
|
||||
LLScrollListText* ageCell = (LLScrollListText*)row->getColumn(ageColumnIndex);
|
||||
ageCell->setColor(LLColor4(options["age_color"]));
|
||||
}
|
||||
}
|
||||
|
|
@ -477,7 +462,7 @@ void FSPanelRadar::onColumnDisplayModeChanged()
|
|||
std::vector<LLScrollListColumn::Params> column_params = mRadarList->getColumnInitParams();
|
||||
S32 column_padding = mRadarList->getColumnPadding();
|
||||
|
||||
LLFloater* parent_floater = nullptr;
|
||||
LLFloater* parent_floater{ nullptr };
|
||||
LLView* parent = getParent();
|
||||
while (parent)
|
||||
{
|
||||
|
|
@ -493,8 +478,8 @@ void FSPanelRadar::onColumnDisplayModeChanged()
|
|||
return;
|
||||
}
|
||||
|
||||
S32 default_width = 0;
|
||||
S32 new_width = 0;
|
||||
S32 default_width{ 0 };
|
||||
S32 new_width{ 0 };
|
||||
S32 min_width, min_height;
|
||||
parent_floater->getResizeLimits(&min_width, &min_height);
|
||||
|
||||
|
|
@ -558,8 +543,7 @@ void FSPanelRadar::onColumnVisibilityChecked(const LLSD& userdata)
|
|||
U32 column_config = gSavedSettings.getU32("FSRadarColumnConfig");
|
||||
|
||||
U32 new_value;
|
||||
U32 enabled = (mColumnBits[column] & column_config);
|
||||
if (enabled)
|
||||
if (U32 enabled = (mColumnBits[column] & column_config); enabled)
|
||||
{
|
||||
new_value = (column_config & ~mColumnBits[column]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ private:
|
|||
|
||||
LLHandle<LLView> mOptionsMenuHandle;
|
||||
|
||||
FSRadar::Updater* mButtonsUpdater;
|
||||
std::unique_ptr<FSRadar::Updater> mButtonsUpdater;
|
||||
|
||||
std::string mFilterSubString;
|
||||
std::string mFilterSubStringOrig;
|
||||
|
|
|
|||
|
|
@ -290,14 +290,13 @@ void FSRadar::updateRadarList()
|
|||
|
||||
// Skip modelling this avatar if its basic data is either inaccessible, or it's a dummy placeholder
|
||||
auto ent = getEntry(avId);
|
||||
LLViewerRegion* reg = world->getRegionFromPosGlobal(avPos);
|
||||
if (!ent) // don't update this radar listing if data is inaccessible
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to get the avatar's viewer object - we will need it anyway later
|
||||
LLVOAvatar* avVo = (LLVOAvatar*)gObjectList.findObject(avId);
|
||||
LLVOAvatar* avVo = static_cast<LLVOAvatar*>(gObjectList.findObject(avId));
|
||||
|
||||
static LLUICachedControl<bool> sFSShowDummyAVsinRadar("FSShowDummyAVsinRadar");
|
||||
if (!sFSShowDummyAVsinRadar && avVo && avVo->mIsDummy)
|
||||
|
|
@ -315,7 +314,7 @@ void FSRadar::updateRadarList()
|
|||
}
|
||||
|
||||
LLUUID avRegion;
|
||||
if (reg)
|
||||
if (LLViewerRegion* reg = world->getRegionFromPosGlobal(avPos); reg)
|
||||
{
|
||||
avRegion = reg->getRegionID();
|
||||
}
|
||||
|
|
@ -595,11 +594,10 @@ void FSRadar::updateRadarList()
|
|||
// Voice power level indicator
|
||||
if (voice_client->voiceEnabled() && voice_client->isVoiceWorking())
|
||||
{
|
||||
LLSpeaker* speaker = speakermgr->findSpeaker(avId);
|
||||
if (speaker && speaker->isInVoiceChannel())
|
||||
if (LLSpeaker* speaker = speakermgr->findSpeaker(avId); speaker && speaker->isInVoiceChannel())
|
||||
{
|
||||
EVoicePowerLevel power_level = voice_client->getPowerLevel(avId);
|
||||
|
||||
|
||||
switch (power_level)
|
||||
{
|
||||
case VPL_PTT_Off:
|
||||
|
|
@ -703,8 +701,7 @@ void FSRadar::updateRadarList()
|
|||
}
|
||||
|
||||
static LLCachedControl<S32> sRadarAlertChannel(gSavedSettings, "RadarAlertChannel");
|
||||
U32 num_entering = (U32)mRadarEnterAlerts.size();
|
||||
if (num_entering > 0)
|
||||
if (U32 num_entering = (U32)mRadarEnterAlerts.size(); num_entering > 0)
|
||||
{
|
||||
mRadarFrameCount++;
|
||||
U32 num_this_pass = llmin(FSRADAR_MAX_AVATARS_PER_ALERT, num_entering);
|
||||
|
|
@ -732,8 +729,8 @@ void FSRadar::updateRadarList()
|
|||
msg = llformat("%d,%d", mRadarFrameCount, num_this_pass);
|
||||
}
|
||||
}
|
||||
U32 num_leaving = (U32)mRadarLeaveAlerts.size();
|
||||
if (num_leaving > 0)
|
||||
|
||||
if (U32 num_leaving = (U32)mRadarLeaveAlerts.size(); num_leaving > 0)
|
||||
{
|
||||
mRadarFrameCount++;
|
||||
U32 num_this_pass = llmin(FSRADAR_MAX_AVATARS_PER_ALERT, num_leaving);
|
||||
|
|
@ -1010,10 +1007,9 @@ void FSRadar::zoomAvatar(const LLUUID& avatar_id, std::string_view name)
|
|||
|
||||
void FSRadar::updateNames()
|
||||
{
|
||||
const entry_map_t::iterator it_end = mEntryList.end();
|
||||
for (entry_map_t::iterator it = mEntryList.begin(); it != it_end; ++it)
|
||||
for (auto& [av_id, entry] : mEntryList)
|
||||
{
|
||||
it->second->updateName();
|
||||
entry->updateName();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,25 +43,23 @@ BOOL FSRadarListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
|
||||
if ( (mContextMenu) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) )
|
||||
{
|
||||
std::vector<LLScrollListItem*> selected_items = getAllSelected();
|
||||
if (selected_items.size() > 1)
|
||||
if (std::vector<LLScrollListItem*> selected_items = getAllSelected(); selected_items.size() > 1)
|
||||
{
|
||||
uuid_vec_t selected_uuids;
|
||||
for (std::vector<LLScrollListItem*>::iterator it = selected_items.begin(); it != selected_items.end(); ++it)
|
||||
for (auto selected_item : selected_items)
|
||||
{
|
||||
selected_uuids.push_back((*it)->getUUID());
|
||||
selected_uuids.emplace_back(selected_item->getUUID());
|
||||
}
|
||||
mContextMenu->show(this, selected_uuids, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLScrollListItem* hit_item = hitItem(x, y);
|
||||
if (hit_item)
|
||||
if (LLScrollListItem* hit_item = hitItem(x, y); hit_item)
|
||||
{
|
||||
selectByID(hit_item->getValue());
|
||||
LLUUID av = hit_item->getValue();
|
||||
uuid_vec_t selected_uuids;
|
||||
selected_uuids.push_back(av);
|
||||
selected_uuids.emplace_back(av);
|
||||
mContextMenu->show(this, selected_uuids, x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public:
|
|||
// not allowed from outside the app
|
||||
FSSlurlCommandHandler() : LLCommandHandler("firestorm", UNTRUSTED_BLOCK) { }
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (params.size() < 2)
|
||||
{
|
||||
|
|
@ -253,7 +253,7 @@ public:
|
|||
// not allowed from outside the app
|
||||
FSHelpSlurlCommandHandler() : LLCommandHandler("fshelp", UNTRUSTED_THROTTLE) { }
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (params.size() < 2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -564,16 +564,13 @@ StrCpy $INSTSHORTCUT "${SHORTCUT}"
|
|||
# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY
|
||||
# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
|
||||
# Couldn't get NSIS to expand $MultiUser.InstallMode into the function name at Call time
|
||||
# <FS:Ansariel> Replaced this with Call un.CheckIfAdministrator since there currently is no InstallMode
|
||||
##${If} $MultiUser.InstallMode == 'AllUsers'
|
||||
${If} $MultiUser.InstallMode == 'AllUsers'
|
||||
##MessageBox MB_OK "Uninstalling for all users"
|
||||
## Call un.MultiUser.InstallMode.AllUsers
|
||||
##${Else}
|
||||
Call un.MultiUser.InstallMode.AllUsers
|
||||
${Else}
|
||||
##MessageBox MB_OK "Uninstalling for current user"
|
||||
## Call un.MultiUser.InstallMode.CurrentUser
|
||||
##${EndIf}
|
||||
Call un.CheckIfAdministrator
|
||||
# </FS:Ansariel>
|
||||
Call un.MultiUser.InstallMode.CurrentUser
|
||||
${EndIf}
|
||||
|
||||
# Make sure we're not running
|
||||
Call un.CloseSecondLife
|
||||
|
|
@ -603,7 +600,7 @@ Call un.UserSettingsFiles
|
|||
SectionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Make sure the user can install
|
||||
;; Make sure the user can install/uninstall
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function CheckIfAdministrator
|
||||
DetailPrint $(CheckAdministratorInstDP)
|
||||
|
|
@ -617,21 +614,6 @@ lbl_is_admin:
|
|||
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Make sure the user can uninstall
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function un.CheckIfAdministrator
|
||||
DetailPrint $(CheckAdministratorUnInstDP)
|
||||
UserInfo::GetAccountType
|
||||
Pop $R0
|
||||
StrCmp $R0 "Admin" lbl_is_admin
|
||||
MessageBox MB_OK $(CheckAdministratorUnInstMB)
|
||||
Quit
|
||||
lbl_is_admin:
|
||||
Return
|
||||
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Function CheckWillUninstallV2
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -440,6 +440,7 @@ LLAgent::LLAgent() :
|
|||
mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mTeleportState(TELEPORT_NONE),
|
||||
mRegionp(NULL),
|
||||
mInterestListMode(LLViewerRegion::IL_MODE_DEFAULT),
|
||||
|
||||
mAgentOriginGlobal(),
|
||||
mPositionGlobal(),
|
||||
|
|
@ -1056,11 +1057,19 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
|
|||
|
||||
// static
|
||||
void LLAgent::capabilityReceivedCallback(const LLUUID ®ion_id, LLViewerRegion *regionp)
|
||||
{
|
||||
if (regionp && regionp->getRegionID() == region_id)
|
||||
{ // Changed regions and now have the region capabilities
|
||||
if (regionp)
|
||||
{
|
||||
regionp->requestSimulatorFeatures();
|
||||
LLAppViewer::instance()->updateNameLookupUrl(regionp);
|
||||
if (regionp->getRegionID() == region_id)
|
||||
{
|
||||
regionp->requestSimulatorFeatures();
|
||||
LLAppViewer::instance()->updateNameLookupUrl(regionp);
|
||||
}
|
||||
|
||||
if (gAgent.getInterestListMode() == LLViewerRegion::IL_MODE_360)
|
||||
{
|
||||
gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_360);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1557,26 +1566,21 @@ LLVector3 LLAgent::getReferenceUpVector()
|
|||
void LLAgent::pitch(F32 angle)
|
||||
{
|
||||
// don't let user pitch if pointed almost all the way down or up
|
||||
mFrameAgent.pitch(clampPitchToLimits(angle));
|
||||
}
|
||||
|
||||
|
||||
// Radians, positive is forward into ground
|
||||
//-----------------------------------------------------------------------------
|
||||
// clampPitchToLimits()
|
||||
//-----------------------------------------------------------------------------
|
||||
F32 LLAgent::clampPitchToLimits(F32 angle)
|
||||
{
|
||||
// A dot B = mag(A) * mag(B) * cos(angle between A and B)
|
||||
// so... cos(angle between A and B) = A dot B / mag(A) / mag(B)
|
||||
// = A dot B for unit vectors
|
||||
|
||||
LLVector3 skyward = getReferenceUpVector();
|
||||
|
||||
const F32 look_down_limit = 179.f * DEG_TO_RAD;;
|
||||
const F32 look_up_limit = 1.f * DEG_TO_RAD;
|
||||
// SL-19286 Avatar is upside down when viewed from below
|
||||
// after left-clicking the mouse on the avatar and dragging down
|
||||
//
|
||||
// The issue is observed on angle below 10 degrees
|
||||
const F32 look_down_limit = 179.f * DEG_TO_RAD;
|
||||
const F32 look_up_limit = 10.f * DEG_TO_RAD;
|
||||
|
||||
F32 angle_from_skyward = acos( mFrameAgent.getAtAxis() * skyward );
|
||||
F32 angle_from_skyward = acos(mFrameAgent.getAtAxis() * skyward);
|
||||
|
||||
// clamp pitch to limits
|
||||
if ((angle >= 0.f) && (angle_from_skyward + angle > look_down_limit))
|
||||
|
|
@ -1587,8 +1591,11 @@ F32 LLAgent::clampPitchToLimits(F32 angle)
|
|||
{
|
||||
angle = look_up_limit - angle_from_skyward;
|
||||
}
|
||||
|
||||
return angle;
|
||||
|
||||
if (fabs(angle) > 1e-4)
|
||||
{
|
||||
mFrameAgent.pitch(angle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3483,39 +3490,60 @@ void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferr
|
|||
handlePreferredMaturityResult(maturity);
|
||||
}
|
||||
|
||||
// Using a new capability, tell the simulator that we want it to send everything
|
||||
// it knows about and not just what is in front of the camera, in its view
|
||||
// frustum. We need this feature so that the contents of the region that appears
|
||||
// in the 6 snapshots which we cannot see and is normally not "considered", is
|
||||
// also rendered. Typically, this is turned on when the 360 capture floater is
|
||||
// opened and turned off when it is closed.
|
||||
// Note: for this version, we do not have a way to determine when "everything"
|
||||
// has arrived and has been rendered so for now, the proposal is that users
|
||||
// will need to experiment with the low resolution version and wait for some
|
||||
// (hopefully) small period of time while the full contents resolves.
|
||||
// Pass in a flag to ask the simulator/interest list to "send everything" or
|
||||
// not (the default mode)
|
||||
void LLAgent::changeInterestListMode(const std::string &new_mode)
|
||||
{
|
||||
if (new_mode != mInterestListMode)
|
||||
{
|
||||
mInterestListMode = new_mode;
|
||||
|
||||
// Change interest list mode for all regions. If they are already set for the current mode,
|
||||
// the setting will have no effect.
|
||||
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
|
||||
iter != LLWorld::getInstance()->getRegionList().end();
|
||||
++iter)
|
||||
{
|
||||
LLViewerRegion *regionp = *iter;
|
||||
if (regionp && regionp->isAlive() && regionp->capabilitiesReceived())
|
||||
{
|
||||
regionp->setInterestListMode(mInterestListMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("360Capture") << "Agent interest list mode is already set to " << mInterestListMode << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure)
|
||||
{
|
||||
if (!getRegion())
|
||||
if (getRegion())
|
||||
{
|
||||
return false;
|
||||
return getRegion()->requestPostCapability(capName, postData, cbSuccess, cbFailure);
|
||||
}
|
||||
std::string url = getRegion()->getCapability(capName);
|
||||
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("Agent") << "Could not retrieve region capability \"" << capName << "\"" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, mHttpPolicy, postData, cbSuccess, cbFailure);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLAgent::requestGetCapability(const std::string &capName, httpCallback_t cbSuccess, httpCallback_t cbFailure)
|
||||
{
|
||||
std::string url;
|
||||
|
||||
url = getRegionCapability(capName);
|
||||
|
||||
if (url.empty())
|
||||
if (getRegion())
|
||||
{
|
||||
LL_WARNS("Agent") << "Could not retrieve region capability \"" << capName << "\"" << LL_ENDL;
|
||||
return false;
|
||||
return getRegion()->requestGetCapability(capName, cbSuccess, cbFailure);
|
||||
}
|
||||
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(url, mHttpPolicy, cbSuccess, cbFailure);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL LLAgent::getAdminOverride() const
|
||||
|
|
|
|||
|
|
@ -298,10 +298,16 @@ public:
|
|||
boost::signals2::connection addRegionChangedCallback(const region_changed_signal_t::slot_type& cb);
|
||||
void removeRegionChangedCallback(boost::signals2::connection callback);
|
||||
|
||||
|
||||
void changeInterestListMode(const std::string & new_mode);
|
||||
const std::string & getInterestListMode() const { return mInterestListMode; }
|
||||
|
||||
private:
|
||||
LLViewerRegion *mRegionp;
|
||||
region_changed_signal_t mRegionChangedSignal;
|
||||
|
||||
std::string mInterestListMode; // How agent wants regions to send updates
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// History
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -638,7 +644,6 @@ public:
|
|||
void roll(F32 angle);
|
||||
void yaw(F32 angle);
|
||||
LLVector3 getReferenceUpVector();
|
||||
F32 clampPitchToLimits(F32 angle);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Autopilot
|
||||
|
|
|
|||
|
|
@ -434,10 +434,15 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
|
|||
|
||||
// if is avatar - don't do any funk heuristics to position the focal point
|
||||
// see DEV-30589
|
||||
if (object->isAvatar() || (object->isAnimatedObject() && object->getControlAvatar()))
|
||||
if ((object->isAvatar() && !object->isRoot()) || (object->isAnimatedObject() && object->getControlAvatar()))
|
||||
{
|
||||
return original_focus_point - obj_pos;
|
||||
}
|
||||
if (object->isAvatar())
|
||||
{
|
||||
LLVOAvatar* av = object->asAvatar();
|
||||
return original_focus_point - av->getCharacterPosition();
|
||||
}
|
||||
|
||||
LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation
|
||||
LLVector3 object_extents = object->getScale();
|
||||
|
|
@ -1871,13 +1876,24 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
LL_WARNS() << "Null avatar drawable!" << LL_ENDL;
|
||||
return LLVector3d::zero;
|
||||
}
|
||||
|
||||
head_offset.clearVec();
|
||||
F32 fixup;
|
||||
if (gAgentAvatarp->hasPelvisFixup(fixup))
|
||||
{
|
||||
head_offset[VZ] -= fixup;
|
||||
}
|
||||
if (gAgentAvatarp->isSitting())
|
||||
{
|
||||
head_offset.mdV[VZ] += 0.1;
|
||||
}
|
||||
|
||||
if (gAgentAvatarp->isSitting() && gAgentAvatarp->getParent())
|
||||
{
|
||||
gAgentAvatarp->updateHeadOffset();
|
||||
head_offset.mdV[VX] = gAgentAvatarp->mHeadOffset.mV[VX];
|
||||
head_offset.mdV[VY] = gAgentAvatarp->mHeadOffset.mV[VY];
|
||||
head_offset.mdV[VZ] = gAgentAvatarp->mHeadOffset.mV[VZ] + 0.1f;
|
||||
head_offset.mdV[VX] += gAgentAvatarp->mHeadOffset.mV[VX];
|
||||
head_offset.mdV[VY] += gAgentAvatarp->mHeadOffset.mV[VY];
|
||||
head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ];
|
||||
const LLMatrix4& mat = ((LLViewerObject*) gAgentAvatarp->getParent())->getRenderMatrix();
|
||||
camera_position_global = gAgent.getPosGlobalFromAgent
|
||||
((gAgentAvatarp->getPosition()+
|
||||
|
|
@ -1885,11 +1901,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
}
|
||||
else
|
||||
{
|
||||
head_offset.mdV[VZ] = gAgentAvatarp->mHeadOffset.mV[VZ];
|
||||
if (gAgentAvatarp->isSitting())
|
||||
{
|
||||
head_offset.mdV[VZ] += 0.1;
|
||||
}
|
||||
head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ];
|
||||
camera_position_global = gAgent.getPosGlobalFromAgent(gAgentAvatarp->getRenderPosition());//frame_center_global;
|
||||
head_offset = head_offset * gAgentAvatarp->getRenderRotation();
|
||||
camera_position_global = camera_position_global + head_offset;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "llcommandhandler.h"
|
||||
#include "llslurl.h"
|
||||
#include "llurldispatcher.h"
|
||||
#include "llviewernetwork.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewerregion.h"
|
||||
|
|
@ -153,7 +154,7 @@ void LLAgentListener::requestTeleport(LLSD const & event_data) const
|
|||
params.append(event_data["x"]);
|
||||
params.append(event_data["y"]);
|
||||
params.append(event_data["z"]);
|
||||
LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, LLCommandHandler::NAV_TYPE_CLICKED, true);
|
||||
LLCommandDispatcher::dispatch("teleport", params, LLSD(), LLGridManager::getInstance()->getGrid(), NULL, LLCommandHandler::NAV_TYPE_CLICKED, true);
|
||||
// *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat"
|
||||
// should we just compose LLCommandHandler and LLDispatchListener?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,9 +104,9 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const
|
|||
|
||||
if (!region || !parcel) return FALSE;
|
||||
|
||||
S32 pos_x = S32(agent_pos_region.mV[VX]);
|
||||
S32 pos_y = S32(agent_pos_region.mV[VY]);
|
||||
S32 pos_z = S32(agent_pos_region.mV[VZ]);
|
||||
S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f);
|
||||
S32 pos_y = S32(agent_pos_region.mV[VY] + 0.5f);
|
||||
S32 pos_z = S32(agent_pos_region.mV[VZ] + 0.5f);
|
||||
|
||||
// Round the numbers based on the velocity
|
||||
F32 velocity_mag_sq = gAgent.getVelocity().magVecSquared();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#include "llinventoryobserver.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "lllocaltextureobject.h"
|
||||
#include "llmd5.h"
|
||||
#include "llmd5.h" // <FS:Ansariel> [Legacy Bake]
|
||||
#include "llnotificationsutil.h"
|
||||
#include "lloutfitobserver.h"
|
||||
#include "llsidepanelappearance.h"
|
||||
|
|
|
|||
|
|
@ -41,7 +41,9 @@
|
|||
#include "llinventorybridge.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llmd5.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llmd5.h"
|
||||
#include "lloutfitobserver.h"
|
||||
#include "lloutfitslist.h"
|
||||
#include "llselectmgr.h"
|
||||
|
|
@ -154,7 +156,10 @@ public:
|
|||
// requests will be throttled from a non-trusted browser
|
||||
LLAppearanceHandler() : LLCommandHandler("appearance", UNTRUSTED_THROTTLE) {}
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
// support secondlife:///app/appearance/show, but for now we just
|
||||
// make all secondlife:///app/appearance SLapps behave this way
|
||||
|
|
@ -5040,8 +5045,10 @@ public:
|
|||
// not allowed from outside the app
|
||||
LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) { }
|
||||
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map,
|
||||
LLMediaCtrl* web)
|
||||
bool handle(const LLSD& tokens,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
LLSD::UUID folder_uuid;
|
||||
|
||||
|
|
|
|||
|
|
@ -1789,7 +1789,12 @@ bool LLAppViewer::doFrame()
|
|||
LLFloaterSimpleOutfitSnapshot::update();
|
||||
gGLActive = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (LLViewerStatsRecorder::instanceExists())
|
||||
{
|
||||
LLViewerStatsRecorder::instance().idle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llagent.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llstartup.h"
|
||||
#include "lltooldraganddrop.h" // pack_permissions_slam
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerregion.h"
|
||||
|
|
@ -488,7 +489,7 @@ void LLAttachmentsMgr::onAttachmentArrived(const LLUUID& inv_item_id)
|
|||
{
|
||||
LLTimer timer;
|
||||
bool expected = mAttachmentRequests.getTime(inv_item_id, timer);
|
||||
if (!expected)
|
||||
if (!expected && LLStartUp::getStartupState() > STATE_WEARABLES_WAIT)
|
||||
{
|
||||
LLInventoryItem *item = gInventory.getItem(inv_item_id);
|
||||
LL_WARNS() << "ATT Attachment was unexpected or arrived after " << MAX_ATTACHMENT_REQUEST_LIFETIME << " seconds: "
|
||||
|
|
@ -532,11 +533,15 @@ void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id)
|
|||
LL_DEBUGS("Avatar") << "ATT all detach requests have completed" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!LLApp::isExiting())
|
||||
{
|
||||
LL_WARNS() << "ATT unexpected detach for "
|
||||
<< (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "ATT detach on shutdown for " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL;
|
||||
}
|
||||
|
||||
// LL_DEBUGS("Avatar") << "ATT detached item flagging as questionable for COF link checking "
|
||||
// << (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public:
|
|||
// requests will be throttled from a non-trusted browser
|
||||
LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_THROTTLE) {}
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
std::string action( "" );
|
||||
if ( params.size() >= 1 )
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public:
|
|||
// requests will be throttled from a non-trusted browser
|
||||
LLObjectIMHandler() : LLCommandHandler("objectim", UNTRUSTED_THROTTLE) {}
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (params.size() < 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class LLObjectHandler : public LLCommandHandler
|
|||
public:
|
||||
LLObjectHandler() : LLCommandHandler("object", UNTRUSTED_BLOCK) { }
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (params.size() < 2) return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@ void LLCommandDispatcherListener::dispatch(const LLSD& params) const
|
|||
// But for testing, allow a caller to specify untrusted.
|
||||
trusted_browser = params["trusted"].asBoolean();
|
||||
}
|
||||
LLCommandDispatcher::dispatch(
|
||||
params["cmd"],
|
||||
LLCommandDispatcher::dispatch(params["cmd"],
|
||||
params["params"],
|
||||
params["query"],
|
||||
"",
|
||||
NULL,
|
||||
LLCommandHandler::NAV_TYPE_CLICKED,
|
||||
trusted_browser);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ public:
|
|||
bool dispatch(const std::string& cmd,
|
||||
const LLSD& params,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web,
|
||||
const std::string& nav_type,
|
||||
bool trusted_browser);
|
||||
|
|
@ -98,6 +99,7 @@ void LLCommandHandlerRegistry::add(const char* cmd,
|
|||
bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
|
||||
const LLSD& params,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web,
|
||||
const std::string& nav_type,
|
||||
bool trusted_browser)
|
||||
|
|
@ -165,7 +167,7 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
|
|||
}
|
||||
}
|
||||
if (!info.mHandler) return false;
|
||||
return info.mHandler->handle(params, query_map, web);
|
||||
return info.mHandler->handle(params, query_map, grid, web);
|
||||
}
|
||||
|
||||
void LLCommandHandlerRegistry::notifySlurlBlocked()
|
||||
|
|
@ -220,12 +222,13 @@ LLCommandHandler::~LLCommandHandler()
|
|||
bool LLCommandDispatcher::dispatch(const std::string& cmd,
|
||||
const LLSD& params,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web,
|
||||
const std::string& nav_type,
|
||||
bool trusted_browser)
|
||||
{
|
||||
return LLCommandHandlerRegistry::instance().dispatch(
|
||||
cmd, params, query_map, web, nav_type, trusted_browser);
|
||||
cmd, params, query_map, grid, web, nav_type, trusted_browser);
|
||||
}
|
||||
|
||||
static std::string lookup(LLCommandHandler::EUntrustedAccess value);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public:
|
|||
LLFooHandler() : LLCommandHandler("foo", UNTRUSTED_BLOCK) { }
|
||||
|
||||
// Your code here
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map,
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
if (tokens.size() < 1) return false;
|
||||
|
|
@ -90,6 +90,7 @@ public:
|
|||
|
||||
virtual bool handle(const LLSD& params,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web) = 0;
|
||||
// For URL secondlife:///app/foo/bar/baz?cat=1&dog=2
|
||||
// @params - array of "bar", "baz", possibly empty
|
||||
|
|
@ -106,6 +107,7 @@ public:
|
|||
static bool dispatch(const std::string& cmd,
|
||||
const LLSD& params,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web,
|
||||
const std::string& nav_type,
|
||||
bool trusted_browser);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ LLControlAvatar::LLControlAvatar(const LLUUID& id, const LLPCode pcode, LLViewer
|
|||
mGlobalScale(1.0f),
|
||||
mMarkedForDeath(false),
|
||||
mRootVolp(NULL),
|
||||
mControlAVBridge(NULL),
|
||||
mScaleConstraintFixup(1.0),
|
||||
mRegionChanged(false)
|
||||
{
|
||||
|
|
@ -379,6 +380,12 @@ void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
}
|
||||
}
|
||||
|
||||
void LLControlAvatar::markDead()
|
||||
{
|
||||
super::markDead();
|
||||
mControlAVBridge = NULL;
|
||||
}
|
||||
|
||||
bool LLControlAvatar::computeNeedsUpdate()
|
||||
{
|
||||
computeUpdatePeriod();
|
||||
|
|
|
|||
|
|
@ -35,9 +35,12 @@ class LLControlAvatar:
|
|||
{
|
||||
LOG_CLASS(LLControlAvatar);
|
||||
|
||||
using super = LLVOAvatar;
|
||||
|
||||
public:
|
||||
LLControlAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
|
||||
virtual void initInstance(); // Called after construction to initialize the class.
|
||||
virtual void initInstance(); // Called after construction to initialize the class.
|
||||
virtual void markDead();
|
||||
virtual ~LLControlAvatar();
|
||||
|
||||
// If this is an attachment, return the avatar it is attached to. Otherwise NULL.
|
||||
|
|
@ -90,6 +93,7 @@ public:
|
|||
F32 mGlobalScale;
|
||||
|
||||
LLVOVolume *mRootVolp;
|
||||
class LLControlAVBridge* mControlAVBridge;
|
||||
|
||||
bool mMarkedForDeath;
|
||||
|
||||
|
|
|
|||
|
|
@ -770,6 +770,19 @@ void LLDrawable::movePartition()
|
|||
if (part)
|
||||
{
|
||||
part->move(this, getSpatialGroup());
|
||||
|
||||
// SL-18251 "On-screen animesh characters using pelvis offset animations
|
||||
// disappear when root goes off-screen"
|
||||
//
|
||||
// Update extents of the root node when Control Avatar changes it's bounds
|
||||
if (mRenderType == LLPipeline::RENDER_TYPE_CONTROL_AV && isRoot())
|
||||
{
|
||||
LLControlAvatar* controlAvatar = dynamic_cast<LLControlAvatar*>(getVObj().get());
|
||||
if (controlAvatar && controlAvatar->mControlAVBridge)
|
||||
{
|
||||
((LLSpatialGroup*)controlAvatar->mControlAVBridge->mOctree->getListener(0))->setState(LLViewerOctreeGroup::DIRTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1231,10 +1244,11 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
|
|||
{
|
||||
setSpatialBridge(new LLHUDBridge(this, getRegion()));
|
||||
}
|
||||
else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar())
|
||||
{
|
||||
setSpatialBridge(new LLControlAVBridge(this, getRegion()));
|
||||
}
|
||||
else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar())
|
||||
{
|
||||
setSpatialBridge(new LLControlAVBridge(this, getRegion()));
|
||||
mVObjp->getControlAvatar()->mControlAVBridge = (LLControlAVBridge*)getSpatialBridge();
|
||||
}
|
||||
// check HUD first, because HUD is also attachment
|
||||
else if (mVObjp->isAttachment())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,8 +47,10 @@ class LLEventHandler : public LLCommandHandler
|
|||
public:
|
||||
// requires trusted browser to trigger
|
||||
LLEventHandler() : LLCommandHandler("event", UNTRUSTED_THROTTLE) { }
|
||||
bool handle(const LLSD& params, const LLSD& query_map,
|
||||
LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
if (params.size() < 2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::st
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outfiles;
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +149,7 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types,
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<std::string> doSaveDialog(const std::string* file,
|
||||
std::unique_ptr<std::string> doSaveDialog(const std::string* file,
|
||||
const std::string* type,
|
||||
const std::string* creator,
|
||||
const std::string* extension,
|
||||
|
|
|
|||
|
|
@ -48,32 +48,9 @@
|
|||
#include "llviewerregion.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "pipeline.h"
|
||||
#include "llworld.h" // </FS:Beq/> needed for getRegionByID();
|
||||
|
||||
#include <iterator>
|
||||
|
||||
// <FS:Beq> Fix 360 capture missing objects after TP
|
||||
void LLFloater360Capture::checkRegion()
|
||||
{
|
||||
static LLUUID last_region_id = LLUUID::null;
|
||||
auto last_region = LLWorld::instance().getRegionFromID(last_region_id);
|
||||
|
||||
// Check if we changed region, if so reset the interest list to full,
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if( region && (region != last_region) )
|
||||
{
|
||||
region->useFullUpdateInterestListMode(true, true);
|
||||
if( last_region )
|
||||
{
|
||||
// we clear the old region status, because the instance may persist for us
|
||||
// but the region itself will have reset when we left.
|
||||
last_region->clearFullUpdateInterestList();
|
||||
}
|
||||
}
|
||||
last_region_id = region->getRegionID();
|
||||
}
|
||||
|
||||
// </FS:Beq>
|
||||
|
||||
LLFloater360Capture::LLFloater360Capture(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
|
|
@ -87,21 +64,10 @@ LLFloater360Capture::LLFloater360Capture(const LLSD& key)
|
|||
// such time as we ask it not to (the dtor). If we crash or
|
||||
// otherwise, exit before this is turned off, the Simulator
|
||||
// will take care of cleaning up for us.
|
||||
if (gSavedSettings.getBOOL("360CaptureUseInterestListCap"))
|
||||
{
|
||||
// <FS:Beq> Fix 360 capture missing objects after TP
|
||||
// send everything to us for as long as this floater is open
|
||||
// const bool send_everything = true;
|
||||
// changeInterestListMode(send_everything);
|
||||
// }
|
||||
// }
|
||||
if( LLViewerRegion* region = gAgent.getRegion() )
|
||||
{
|
||||
checkRegion();
|
||||
}
|
||||
}
|
||||
mRegionChangeConnection = gAgent.addRegionChangedCallback(boost::bind(&LLFloater360Capture::checkRegion, this));
|
||||
// </FS:Beq>
|
||||
mStartILMode = gAgent.getInterestListMode();
|
||||
|
||||
// send everything to us for as long as this floater is open
|
||||
gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_360);
|
||||
}
|
||||
|
||||
LLFloater360Capture::~LLFloater360Capture()
|
||||
|
|
@ -113,27 +79,16 @@ LLFloater360Capture::~LLFloater360Capture()
|
|||
mWebBrowser->unloadMediaSource();
|
||||
}
|
||||
|
||||
// Tell the Simulator not to send us everything anymore
|
||||
// and revert to the regular "keyhole" frustum of interest
|
||||
// Restore interest list mode to the state when started
|
||||
// Normally LLFloater360Capture tells the Simulator send everything
|
||||
// and now reverts to the regular "keyhole" frustum of interest
|
||||
// list updates.
|
||||
if (!LLApp::isExiting() && gSavedSettings.getBOOL("360CaptureUseInterestListCap"))
|
||||
if (!LLApp::isExiting() &&
|
||||
gSavedSettings.getBOOL("360CaptureUseInterestListCap") &&
|
||||
mStartILMode != gAgent.getInterestListMode())
|
||||
{
|
||||
// <FS:Beq> Fix 360 capture missing objects after TP
|
||||
// const bool send_everything = false;
|
||||
// changeInterestListMode(send_everything);
|
||||
// }
|
||||
// }
|
||||
|
||||
if( LLViewerRegion* region = gAgent.getRegion() )
|
||||
{
|
||||
region->useFullUpdateInterestListMode(false);
|
||||
}
|
||||
gAgent.changeInterestListMode(mStartILMode);
|
||||
}
|
||||
if (mRegionChangeConnection.connected())
|
||||
{
|
||||
mRegionChangeConnection.disconnect();
|
||||
}
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
BOOL LLFloater360Capture::postBuild()
|
||||
|
|
@ -216,54 +171,6 @@ void LLFloater360Capture::onChooseQualityRadioGroup()
|
|||
setSourceImageSize();
|
||||
}
|
||||
|
||||
// <FS:Beq> Area search improvements - allow area search and 360 to coexist nicely.
|
||||
// Code moved to LLViewerRegion.cpp
|
||||
// Using a new capability, tell the simulator that we want it to send everything
|
||||
// it knows about and not just what is in front of the camera, in its view
|
||||
// frustum. We need this feature so that the contents of the region that appears
|
||||
// in the 6 snapshots which we cannot see and is normally not "considered", is
|
||||
// also rendered. Typically, this is turned on when the 360 capture floater is
|
||||
// opened and turned off when it is closed.
|
||||
// Note: for this version, we do not have a way to determine when "everything"
|
||||
// has arrived and has been rendered so for now, the proposal is that users
|
||||
// will need to experiment with the low resolution version and wait for some
|
||||
// (hopefully) small period of time while the full contents resolves.
|
||||
// Pass in a flag to ask the simulator/interest list to "send everything" or
|
||||
// not (the default mode)
|
||||
// void LLFloater360Capture::changeInterestListMode(bool send_everything)
|
||||
// {
|
||||
// LLSD body;
|
||||
// if (send_everything)
|
||||
// {
|
||||
// body["mode"] = LLSD::String("360");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// body["mode"] = LLSD::String("default");
|
||||
// }
|
||||
|
||||
// if (gAgent.requestPostCapability("InterestList", body, [](const LLSD & response)
|
||||
// {
|
||||
// LL_INFOS("360Capture") <<
|
||||
// "InterestList capability responded: \n" <<
|
||||
// ll_pretty_print_sd(response) <<
|
||||
// LL_ENDL;
|
||||
// }))
|
||||
// {
|
||||
// LL_INFOS("360Capture") <<
|
||||
// "Successfully posted an InterestList capability request with payload: \n" <<
|
||||
// ll_pretty_print_sd(body) <<
|
||||
// LL_ENDL;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// LL_INFOS("360Capture") <<
|
||||
// "Unable to post an InterestList capability request with payload: \n" <<
|
||||
// ll_pretty_print_sd(body) <<
|
||||
// LL_ENDL;
|
||||
// }
|
||||
// }
|
||||
// </FS:Beq>
|
||||
|
||||
// There is is a setting (360CaptureSourceImageSize) that holds the size
|
||||
// (width == height since it's a square) of each of the 6 source snapshots.
|
||||
|
|
@ -683,11 +590,8 @@ void LLFloater360Capture::capture360Images()
|
|||
// display time to encode all 6 images. It tends to be a fairly linear
|
||||
// time for each so we don't need to worry about displaying the time
|
||||
// for each - this gives us plenty to use for optimizing
|
||||
LL_INFOS("360Capture") <<
|
||||
"Time to encode and save 6 images was " <<
|
||||
encode_time_total <<
|
||||
" seconds" <<
|
||||
LL_ENDL;
|
||||
LL_INFOS("360Capture") << "Time to encode and save 6 images was " <<
|
||||
encode_time_total << " seconds" << LL_ENDL;
|
||||
|
||||
// Write the JavaScript file footer (the bottom of the file after the
|
||||
// declarations of the actual data URLs array). The footer comprises of
|
||||
|
|
@ -719,7 +623,7 @@ void LLFloater360Capture::capture360Images()
|
|||
// as a change - only the subsequent 5 are
|
||||
if (camera_changed_times < 5)
|
||||
{
|
||||
LL_INFOS("360Capture") << "Warning: we only captured " << camera_changed_times << " images." << LL_ENDL;
|
||||
LL_WARNS("360Capture") << "360 image capture expected 5 or more images, only captured " << camera_changed_times << " images." << LL_ENDL;
|
||||
}
|
||||
|
||||
// now we have the 6 shots saved in a well specified location,
|
||||
|
|
|
|||
|
|
@ -50,14 +50,9 @@ class LLFloater360Capture:
|
|||
void onOpen(const LLSD& key) override;
|
||||
void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
|
||||
|
||||
// void changeInterestListMode(bool send_everything); // <FS:Beq/> Area search improvements - code relocated to LLViewerRegion
|
||||
|
||||
const std::string getHTMLBaseFolder();
|
||||
void capture360Images();
|
||||
// <FS:Beq/> make 360 work properly after region crossing/TP
|
||||
void checkRegion();
|
||||
boost::signals2::connection mRegionChangeConnection;
|
||||
// </FS:Beq>
|
||||
|
||||
const std::string makeFullPathToJS(const std::string filename);
|
||||
void writeDataURLHeader(const std::string filename);
|
||||
void writeDataURLFooter(const std::string filename);
|
||||
|
|
@ -96,6 +91,8 @@ class LLFloater360Capture:
|
|||
std::string mImageSaveDir;
|
||||
|
||||
LLPointer<LLImageRaw> mRawImages[6];
|
||||
|
||||
std::string mStartILMode;
|
||||
};
|
||||
|
||||
#endif // LL_FLOATER_360CAPTURE_H
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloatercamera.h"
|
||||
#include "llfloatercamerapresets.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llnotificationsutil.h"
|
||||
|
|
@ -40,7 +41,8 @@ LLFloaterCameraPresets::~LLFloaterCameraPresets()
|
|||
BOOL LLFloaterCameraPresets::postBuild()
|
||||
{
|
||||
mPresetList = getChild<LLFlatListView>("preset_list");
|
||||
|
||||
mPresetList->setCommitCallback(boost::bind(&LLFloaterCameraPresets::onSelectionChange, this));
|
||||
mPresetList->setCommitOnSelectionChange(true);
|
||||
LLPresetsManager::getInstance()->setPresetListChangeCameraCallback(boost::bind(&LLFloaterCameraPresets::populateList, this));
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -58,6 +60,7 @@ void LLFloaterCameraPresets::populateList()
|
|||
std::list<std::string> preset_names;
|
||||
|
||||
presetsMgr->loadPresetNamesFromDir(PRESETS_CAMERA, preset_names, DEFAULT_BOTTOM);
|
||||
std::string active_preset = gSavedSettings.getString("PresetCameraActive");
|
||||
|
||||
for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
|
||||
{
|
||||
|
|
@ -66,6 +69,19 @@ void LLFloaterCameraPresets::populateList()
|
|||
LLCameraPresetFlatItem* item = new LLCameraPresetFlatItem(name, is_default);
|
||||
item->postBuild();
|
||||
mPresetList->addItem(item);
|
||||
if(name == active_preset)
|
||||
{
|
||||
mPresetList->selectItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterCameraPresets::onSelectionChange()
|
||||
{
|
||||
LLCameraPresetFlatItem* selected_preset = dynamic_cast<LLCameraPresetFlatItem*>(mPresetList->getSelectedItem());
|
||||
if(selected_preset)
|
||||
{
|
||||
LLFloaterCamera::switchToPreset(selected_preset->getPresetName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class LLFloaterCameraPresets : public LLFloater
|
|||
virtual void onOpen(const LLSD& key);
|
||||
|
||||
void populateList();
|
||||
void onSelectionChange();
|
||||
|
||||
private:
|
||||
LLFloaterCameraPresets(const LLSD& key);
|
||||
|
|
@ -58,6 +59,8 @@ public:
|
|||
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
||||
std::string getPresetName() { return mPresetName; }
|
||||
|
||||
private:
|
||||
void onDeleteBtnClick();
|
||||
void onResetBtnClick();
|
||||
|
|
|
|||
|
|
@ -92,8 +92,10 @@ class LLExperienceHandler : public LLCommandHandler
|
|||
public:
|
||||
LLExperienceHandler() : LLCommandHandler("experience", UNTRUSTED_THROTTLE) { }
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map,
|
||||
LLMediaCtrl* web)
|
||||
bool handle(const LLSD& params,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
if(params.size() != 2 || params[1].asString() != "profile")
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ LLFloater* get_parent_floater(LLView* view)
|
|||
}
|
||||
|
||||
|
||||
bool LLFloaterHandler::handle(const LLSD ¶ms, const LLSD &query_map, LLMediaCtrl *web)
|
||||
bool LLFloaterHandler::handle(const LLSD ¶ms, const LLSD &query_map, const std::string& grid, LLMediaCtrl *web)
|
||||
{
|
||||
if (params.size() < 1) return false;
|
||||
LLFloater* floater = NULL;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class LLFloaterHandler
|
|||
{
|
||||
public:
|
||||
LLFloaterHandler() : LLCommandHandler("floater", UNTRUSTED_BLOCK) { }
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web);
|
||||
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -967,8 +967,10 @@ public:
|
|||
LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
|
||||
|
||||
// Your code here
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map,
|
||||
LLMediaCtrl* web)
|
||||
bool handle(const LLSD& tokens,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
bool retval = false;
|
||||
// Need at least 2 tokens to have a valid message.
|
||||
|
|
|
|||
|
|
@ -3031,7 +3031,7 @@ BOOL LLPanelEstateAccess::postBuild()
|
|||
if (banned_name_list)
|
||||
{
|
||||
banned_name_list->setCommitOnSelectionChange(TRUE);
|
||||
banned_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS);
|
||||
banned_name_list->setMaxItemCount(LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_BANNED_IDS : ESTATE_MAX_BANNED_IDS_OS); // <FS:Ansariel> OpenSim
|
||||
}
|
||||
|
||||
getChild<LLUICtrl>("banned_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onBannedSearchEdit, this, _2));
|
||||
|
|
@ -3044,7 +3044,7 @@ BOOL LLPanelEstateAccess::postBuild()
|
|||
if (manager_name_list)
|
||||
{
|
||||
manager_name_list->setCommitOnSelectionChange(TRUE);
|
||||
manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue
|
||||
manager_name_list->setMaxItemCount((LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_MANAGERS : ESTATE_MAX_MANAGERS_OS) * 4); // Allow extras for dupe issue // <FS:Ansariel> OpenSim
|
||||
}
|
||||
|
||||
childSetAction("add_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickAddEstateManager, this));
|
||||
|
|
@ -3175,10 +3175,10 @@ void LLPanelEstateAccess::onClickAddBannedAgent()
|
|||
{
|
||||
LLCtrlListInterface *list = childGetListInterface("banned_avatar_name_list");
|
||||
if (!list) return;
|
||||
if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
|
||||
if (list->getItemCount() >= (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_BANNED_IDS : ESTATE_MAX_BANNED_IDS_OS)) // <FS:Ansariel> OpenSim
|
||||
{
|
||||
LLSD args;
|
||||
args["MAX_BANNED"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
|
||||
args["MAX_BANNED"] = llformat("%d", (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_BANNED_IDS : ESTATE_MAX_BANNED_IDS_OS)); // <FS:Ansariel> OpenSim
|
||||
LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args);
|
||||
return;
|
||||
}
|
||||
|
|
@ -3210,10 +3210,10 @@ void LLPanelEstateAccess::onClickAddEstateManager()
|
|||
{
|
||||
LLCtrlListInterface *list = childGetListInterface("estate_manager_name_list");
|
||||
if (!list) return;
|
||||
if (list->getItemCount() >= ESTATE_MAX_MANAGERS)
|
||||
if (list->getItemCount() >= (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_MANAGERS : ESTATE_MAX_MANAGERS_OS)) // <FS:Ansariel> OpenSim
|
||||
{ // Tell user they can't add more managers
|
||||
LLSD args;
|
||||
args["MAX_MANAGER"] = llformat("%d", ESTATE_MAX_MANAGERS);
|
||||
args["MAX_MANAGER"] = llformat("%d", (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_MANAGERS : ESTATE_MAX_MANAGERS_OS)); // <FS:Ansariel> OpenSim
|
||||
LLNotificationsUtil::add("MaxManagersOnRegion", args);
|
||||
}
|
||||
else
|
||||
|
|
@ -3416,13 +3416,13 @@ void LLPanelEstateAccess::accessAddCore3(const uuid_vec_t& ids, std::vector<LLAv
|
|||
LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list");
|
||||
LLNameListCtrl* em_list = panel->getChild<LLNameListCtrl>("estate_manager_name_list");
|
||||
int currentCount = (name_list ? name_list->getItemCount() : 0);
|
||||
if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS)
|
||||
if (ids.size() + currentCount > (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_BANNED_IDS : ESTATE_MAX_BANNED_IDS_OS)) // <FS:Ansariel> OpenSim
|
||||
{
|
||||
LLSD args;
|
||||
args["NUM_ADDED"] = llformat("%d", ids.size());
|
||||
args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
|
||||
args["MAX_AGENTS"] = llformat("%d", (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_BANNED_IDS : ESTATE_MAX_BANNED_IDS_OS)); // <FS:Ansariel> OpenSim
|
||||
args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
|
||||
args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_ACCESS_IDS);
|
||||
args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_BANNED_IDS : ESTATE_MAX_BANNED_IDS_OS)); // <FS:Ansariel> OpenSim
|
||||
LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
|
||||
delete change_info;
|
||||
return;
|
||||
|
|
@ -3801,7 +3801,7 @@ void LLPanelEstateAccess::requestEstateGetAccessCoro(std::string url)
|
|||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[BANNEDAGENTS]"] = llformat("%d", result["BannedAgents"].size());
|
||||
args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
|
||||
args["[MAXBANNED]"] = llformat("%d", (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_BANNED_IDS : ESTATE_MAX_BANNED_IDS_OS)); // <FS:Ansariel> OpenSim
|
||||
std::string msg = LLTrans::getString("RegionInfoBannedResidents", args);
|
||||
panel->getChild<LLUICtrl>("ban_resident_label")->setValue(LLSD(msg));
|
||||
|
||||
|
|
@ -3863,7 +3863,7 @@ void LLPanelEstateAccess::requestEstateGetAccessCoro(std::string url)
|
|||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[ESTATEMANAGERS]"] = llformat("%d", result["Managers"].size());
|
||||
args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS);
|
||||
args["[MAXMANAGERS]"] = llformat("%d", (LLGridManager::instance().isInSecondLife() ? ESTATE_MAX_MANAGERS : ESTATE_MAX_MANAGERS_OS)); // <FS:Ansariel> OpenSim
|
||||
std::string msg = LLTrans::getString("RegionInfoEstateManagers", args);
|
||||
panel->getChild<LLUICtrl>("estate_manager_label")->setValue(LLSD(msg));
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class LLSearchHandler : public LLCommandHandler
|
|||
public:
|
||||
// requires trusted browser to trigger
|
||||
LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_CLICK_ONLY) { }
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableSearch"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llfloaterregioninfo.h"
|
||||
|
||||
|
|
@ -89,7 +90,9 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key)
|
|||
mCommitCallbackRegistrar.add("TopObjects.GetByParcelName", boost::bind(&LLFloaterTopObjects::onGetByParcelName, this));
|
||||
mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this));
|
||||
|
||||
|
||||
// <FS:Ansariel> TP to object
|
||||
//mCommitCallbackRegistrar.add("TopObjects.TeleportToSelected", boost::bind(&LLFloaterTopObjects::teleportToSelectedObject, this));
|
||||
mCommitCallbackRegistrar.add("TopObjects.TeleportToObject", boost::bind(&LLFloaterTopObjects::onTeleportToObject, this));
|
||||
// <FS:Ansariel> Estate kick avatar
|
||||
mCommitCallbackRegistrar.add("TopObjects.Kick", boost::bind(&LLFloaterTopObjects::onKick, this));
|
||||
|
|
@ -106,10 +109,11 @@ LLFloaterTopObjects::~LLFloaterTopObjects()
|
|||
// virtual
|
||||
BOOL LLFloaterTopObjects::postBuild()
|
||||
{
|
||||
LLScrollListCtrl *objects_list = getChild<LLScrollListCtrl>("objects_list");
|
||||
getChild<LLUICtrl>("objects_list")->setFocus(TRUE);
|
||||
objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this);
|
||||
objects_list->setCommitOnSelectionChange(TRUE);
|
||||
mObjectsScrollList = getChild<LLScrollListCtrl>("objects_list");
|
||||
mObjectsScrollList->setFocus(TRUE);
|
||||
mObjectsScrollList->setDoubleClickCallback(onDoubleClickObjectsList, this);
|
||||
mObjectsScrollList->setCommitOnSelectionChange(TRUE);
|
||||
mObjectsScrollList->setCommitCallback(boost::bind(&LLFloaterTopObjects::onSelectionChanged, this));
|
||||
|
||||
setDefaultBtn("show_beacon_btn");
|
||||
|
||||
|
|
@ -453,6 +457,8 @@ void LLFloaterTopObjects::clearList()
|
|||
mObjectListData.clear();
|
||||
mObjectListIDs.clear();
|
||||
mtotalScore = 0.f;
|
||||
|
||||
onSelectionChanged();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -541,12 +547,53 @@ void LLFloaterTopObjects::showBeacon()
|
|||
}
|
||||
|
||||
// </FS:Ansariel> TP to object
|
||||
//void LLFloaterTopObjects::teleportToSelectedObject()
|
||||
//{
|
||||
// std::vector<LLScrollListItem*> selected_items = mObjectsScrollList->getAllSelected();
|
||||
// if (selected_items.size() == 1)
|
||||
// {
|
||||
// LLScrollListItem* first_selected = selected_items.front();
|
||||
//
|
||||
// LLVector3d teleport_location;
|
||||
// LLViewerObject* viewer_object = gObjectList.findObject(first_selected->getUUID());
|
||||
// if (viewer_object == NULL)
|
||||
// {
|
||||
// // If we cannot find the object in the viewer list, teleport to the last reported position
|
||||
// std::string pos_string = first_selected->getColumn(3)->getValue().asString();
|
||||
//
|
||||
// F32 x, y, z;
|
||||
// S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);
|
||||
// if (matched != 3) return;
|
||||
//
|
||||
// LLVector3 pos_agent(x, y, z);
|
||||
// teleport_location = gAgent.getPosGlobalFromAgent(pos_agent);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // If we can find the object in the viewer list, teleport to the known current position
|
||||
// teleport_location = viewer_object->getPositionGlobal();
|
||||
// }
|
||||
// gAgent.teleportViaLocationLookAt(teleport_location);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void LLFloaterTopObjects::onSelectionChanged()
|
||||
//{
|
||||
// getChildView("teleport_btn")->setEnabled(mObjectsScrollList->getNumSelected() == 1);
|
||||
//}
|
||||
//
|
||||
void LLFloaterTopObjects::onSelectionChanged()
|
||||
{
|
||||
bool enabled = mObjectsScrollList->getNumSelected() == 1;
|
||||
childSetEnabled("teleport_to_btn", enabled);
|
||||
childSetEnabled("profile_btn", enabled);
|
||||
childSetEnabled("script_info_btn", enabled);
|
||||
childSetEnabled("estate_kick_btn", enabled);
|
||||
}
|
||||
|
||||
void LLFloaterTopObjects::onTeleportToObject()
|
||||
{
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
|
||||
if (!list) return;
|
||||
|
||||
LLScrollListItem* first_selected = list->getFirstSelected();
|
||||
LLScrollListItem* first_selected = mObjectsScrollList->getFirstSelected();
|
||||
if (!first_selected) return;
|
||||
|
||||
std::string pos_string = first_selected->getColumn(3)->getValue().asString();
|
||||
|
|
@ -565,10 +612,7 @@ void LLFloaterTopObjects::onTeleportToObject()
|
|||
// <FS:Ansariel> Estate kick avatar
|
||||
void LLFloaterTopObjects::onKick()
|
||||
{
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
|
||||
if (!list) return;
|
||||
|
||||
LLScrollListItem* first_selected = list->getFirstSelected();
|
||||
LLScrollListItem* first_selected = mObjectsScrollList->getFirstSelected();
|
||||
if (!first_selected) return;
|
||||
|
||||
const LLUUID& objectId = first_selected->getUUID();
|
||||
|
|
@ -579,10 +623,7 @@ void LLFloaterTopObjects::onKick()
|
|||
// <FS:Ansariel> Show profile
|
||||
void LLFloaterTopObjects::onProfile()
|
||||
{
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
|
||||
if (!list) return;
|
||||
|
||||
LLScrollListItem* first_selected = list->getFirstSelected();
|
||||
LLScrollListItem* first_selected = mObjectsScrollList->getFirstSelected();
|
||||
if (!first_selected) return;
|
||||
|
||||
const LLUUID& objectId = first_selected->getUUID();
|
||||
|
|
@ -593,10 +634,7 @@ void LLFloaterTopObjects::onProfile()
|
|||
// <FS:Ansariel> Enable avatar-specific buttons if current selection is an avatar
|
||||
void LLFloaterTopObjects::onAvatarCheck(const LLUUID& avatar_id, LLAvatarName av_name)
|
||||
{
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
|
||||
if (!list) return;
|
||||
|
||||
LLScrollListItem* first_selected = list->getFirstSelected();
|
||||
LLScrollListItem* first_selected = mObjectsScrollList->getFirstSelected();
|
||||
if (!first_selected) return;
|
||||
|
||||
if (first_selected->getUUID() == avatar_id)
|
||||
|
|
@ -611,10 +649,7 @@ void LLFloaterTopObjects::onAvatarCheck(const LLUUID& avatar_id, LLAvatarName av
|
|||
// <FS:Ansariel> Script info
|
||||
void LLFloaterTopObjects::onScriptInfo()
|
||||
{
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
|
||||
if (!list) return;
|
||||
|
||||
LLScrollListItem* first_selected = list->getFirstSelected();
|
||||
LLScrollListItem* first_selected = mObjectsScrollList->getFirstSelected();
|
||||
if (!first_selected) return;
|
||||
|
||||
const LLUUID& objectId = first_selected->getUUID();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue