merge changes for storm-250
commit
c77fcfb7a8
|
|
@ -11,7 +11,10 @@ syntax: glob
|
|||
*.DS_Store
|
||||
LICENSES
|
||||
indra/.distcc
|
||||
indra/build-darwin-*
|
||||
build-linux-*
|
||||
build-darwin-*
|
||||
build-vc80/
|
||||
build-vc100/
|
||||
indra/build-vc[0-9]*
|
||||
indra/CMakeFiles
|
||||
indra/lib/mono/1.0/*.dll
|
||||
|
|
|
|||
22
.hgtags
22
.hgtags
|
|
@ -52,6 +52,7 @@ a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start
|
|||
345b17e7cf630db77e840b4fe3451bd476d750a3 76f586a8e22b
|
||||
0000000000000000000000000000000000000000 76f586a8e22b
|
||||
54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
|
||||
b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
|
||||
7076e22f9f43f479a4ea75eac447a36364bead5a DRTVWR-5_2.2.0-beta1
|
||||
9822eb3e25f7fe0c28ffd8aba45c507caa383cbc DRTVWR-3_2.2.0-beta2
|
||||
b0cd7e150009809a0b5b0a9d5785cd4bb230413a DRTVWR-7_2.2.0-beta3
|
||||
|
|
@ -70,6 +71,7 @@ b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
|
|||
b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
|
||||
b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
|
||||
92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start
|
||||
3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
|
||||
63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
|
||||
4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
|
||||
4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
|
||||
|
|
@ -79,3 +81,23 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 2.5.2-release
|
|||
f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
|
||||
f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
|
||||
4e9eec6a347f89b2b3f295beb72f1cf7837dff66 2.6.0-start
|
||||
9283d6d1d7eb71dfe4c330e7c9144857e7356bde 2.6.0-beta1
|
||||
9283d6d1d7eb71dfe4c330e7c9144857e7356bde DRTVWR-40_2.6.0-beta1
|
||||
9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
|
||||
9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
|
||||
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
|
||||
c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
|
||||
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
|
||||
9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
|
||||
9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
|
||||
c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
|
||||
c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
|
||||
56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
|
||||
42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
|
||||
42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
|
||||
d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
|
||||
d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
|
||||
52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py
|
||||
ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start
|
||||
d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
|
||||
d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1
|
||||
|
|
|
|||
80
BuildParams
80
BuildParams
|
|
@ -61,7 +61,6 @@ viewer-release.viewer_channel = "Second Life Release"
|
|||
viewer-release.login_channel = "Second Life Release"
|
||||
viewer-release.build_debug_release_separately = true
|
||||
viewer-release.build_viewer_update_version_manager = true
|
||||
viewer-release.release-viewer.jira = DRTVWR-13
|
||||
|
||||
viewer-pre-release.viewer_channel = "Second Life Release"
|
||||
viewer-pre-release.login_channel = "Second Life Release"
|
||||
|
|
@ -69,14 +68,6 @@ viewer-pre-release.build_debug_release_separately = true
|
|||
viewer-pre-release.build_viewer_update_version_manager = true
|
||||
#viewer-pre-release.release-viewer.jira = DRTVWR-13
|
||||
|
||||
# ========================================
|
||||
# aimee
|
||||
# ========================================
|
||||
|
||||
viewer-development-import.build_debug_release_separately = true
|
||||
viewer-development-fixes.build_debug_release_separately = true
|
||||
viewer-development-tweaks.build_debug_release_separately = true
|
||||
|
||||
# =======================================
|
||||
# brad
|
||||
# ========================================
|
||||
|
|
@ -164,55 +155,10 @@ media.build_viewer_update_version_manager = false
|
|||
# oz
|
||||
# ================
|
||||
|
||||
oz_viewer-review1_coverity.coverity_product = viewer
|
||||
|
||||
oz_viewer-review1.build_Linux = true
|
||||
oz_viewer-review1_debug.build_Linux = false
|
||||
oz_viewer-review1_coverity.build_Linux = false
|
||||
|
||||
oz_viewer-review1.build_Darwin = true
|
||||
oz_viewer-review1_debug.build_Darwin = false
|
||||
oz_viewer-review1_coverity.build_Darwin = false
|
||||
|
||||
oz_viewer-review1.build_CYGWIN = true
|
||||
oz_viewer-review1.build_CYGWIN_Debug = false
|
||||
oz_viewer-review1.build_CYGWIN_RelWithDebInfo = false
|
||||
oz_viewer-review1.build_CYGWIN_Release = true
|
||||
oz_viewer-review1_debug.build_CYGWIN_Debug = true
|
||||
oz_viewer-review1_debug.build_CYGWIN_RelWithDebInfo = true
|
||||
oz_viewer-review1_debug.build_CYGWIN_Release = false
|
||||
oz_viewer-review1_coverity.build_coverity = true
|
||||
oz_viewer-review1_coverity.build_CYGWIN_Debug = false
|
||||
oz_viewer-review1_coverity.build_CYGWIN_RelWithDebInfo = false
|
||||
oz_viewer-review1_coverity.build_CYGWIN_Release = false
|
||||
|
||||
oz_viewer-review2_coverity.coverity_product = viewer
|
||||
|
||||
oz_viewer-review2.build_Linux = true
|
||||
oz_viewer-review2_debug.build_Linux = false
|
||||
oz_viewer-review2_coverity.build_Linux = false
|
||||
|
||||
oz_viewer-review2.build_Darwin = true
|
||||
oz_viewer-review2_debug.build_Darwin = false
|
||||
oz_viewer-review2_coverity.build_Darwin = false
|
||||
|
||||
oz_viewer-review2.build_CYGWIN = true
|
||||
oz_viewer-review2.build_CYGWIN_Debug = false
|
||||
oz_viewer-review2.build_CYGWIN_RelWithDebInfo = false
|
||||
oz_viewer-review2.build_CYGWIN_Release = true
|
||||
oz_viewer-review2_debug.build_CYGWIN_Debug = true
|
||||
oz_viewer-review2_debug.build_CYGWIN_RelWithDebInfo = true
|
||||
oz_viewer-review2_debug.build_CYGWIN_Release = false
|
||||
oz_viewer-review2_coverity.build_coverity = true
|
||||
oz_viewer-review2_coverity.build_CYGWIN_Debug = false
|
||||
oz_viewer-review2_coverity.build_CYGWIN_RelWithDebInfo = false
|
||||
oz_viewer-review2_coverity.build_CYGWIN_Release = false
|
||||
|
||||
# ========================================
|
||||
# tofu
|
||||
# ========================================
|
||||
|
||||
tofu_viewer-development-staging.email = tofu.linden@lindenlab.com
|
||||
oz_viewer-devreview.build_debug_release_separately = true
|
||||
oz_project-1.build_debug_release_separately = true
|
||||
oz_project-2.build_debug_release_separately = true
|
||||
oz_project-3.build_debug_release_separately = true
|
||||
|
||||
# ========================================
|
||||
# enus
|
||||
|
|
@ -246,5 +192,23 @@ viewer-asset-delivery-metrics.email = monty@lindenlab.com
|
|||
viewer-asset-delivery-metrics.build_server = false
|
||||
viewer-asset-delivery-metrics.build_server_tests = false
|
||||
|
||||
#==============================================================================
|
||||
# autobuild viewers
|
||||
#==============================================================================
|
||||
viewer-autobuild2010.build_debug_release_separately = true
|
||||
viewer-autobuild2010.viewer_channel = "Project Viewer - VS2010"
|
||||
viewer-autobuild2010.login_channel = "Project Viewer - VS2010"
|
||||
viewer-autobuild2010.viewer_grid = agni
|
||||
viewer-autobuild2010.build_link_parallel = false
|
||||
|
||||
#========================================
|
||||
# VS2010
|
||||
#========================================
|
||||
viewer-vs2010.viewer_channel = "Project Viewer - VS2010"
|
||||
viewer-vs2010.login_channel = "Project Viewer - VS2010"
|
||||
viewer-vs2010.viewer_grid = agni
|
||||
viewer-vs2010.build_debug_release_separately = true
|
||||
viewer-vs2010.build_viewer_update_version_manager = false
|
||||
viewer-vs2010.build_link_parallel = false
|
||||
|
||||
# eof
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
170
build.sh
170
build.sh
|
|
@ -22,12 +22,12 @@ build_dir_Darwin()
|
|||
|
||||
build_dir_Linux()
|
||||
{
|
||||
echo viewer-linux-i686-$(echo $1 | tr A-Z a-z)
|
||||
echo build-linux-i686
|
||||
}
|
||||
|
||||
build_dir_CYGWIN()
|
||||
{
|
||||
echo build-vc80
|
||||
echo build-vc100
|
||||
}
|
||||
|
||||
installer_Darwin()
|
||||
|
|
@ -50,47 +50,30 @@ installer_CYGWIN()
|
|||
pre_build()
|
||||
{
|
||||
local variant="$1"
|
||||
local build_dir="$2"
|
||||
begin_section "Pre$variant"
|
||||
#export PATH="/cygdrive/c/Program Files/Microsoft Visual Studio 8/Common7/IDE/:$PATH"
|
||||
python develop.py \
|
||||
--incredibuild \
|
||||
--unattended \
|
||||
-t $variant \
|
||||
-G "$cmake_generator" \
|
||||
configure \
|
||||
-DGRID:STRING="$viewer_grid" \
|
||||
-DVIEWER_CHANNEL:STRING="$viewer_channel" \
|
||||
-DVIEWER_LOGIN_CHANNEL:STRING="$login_channel" \
|
||||
-DINSTALL_PROPRIETARY:BOOL=ON \
|
||||
-DRELEASE_CRASH_REPORTING:BOOL=ON \
|
||||
-DLOCALIZESETUP:BOOL=ON \
|
||||
-DPACKAGE:BOOL=ON \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE \
|
||||
-DLL_TESTS:BOOL="$run_tests"
|
||||
end_section "Pre$variant"
|
||||
[ -n "$master_message_template_checkout" ] \
|
||||
&& [ -r "$master_message_template_checkout/message_template.msg" ] \
|
||||
&& template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
|
||||
|
||||
"$AUTOBUILD" configure -c $variant -- \
|
||||
-DPACKAGE:BOOL=ON \
|
||||
-DRELEASE_CRASH_REPORTING:BOOL=ON \
|
||||
-DUSE_PRECOMPILED_HEADERS=FALSE \
|
||||
-DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \
|
||||
-DVIEWER_LOGIN_CHANNEL:STRING="\"$viewer_login_channel\"" \
|
||||
-DGRID:STRING="\"$viewer_grid\"" \
|
||||
-DLL_TESTS:BOOL="$run_tests" \
|
||||
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url
|
||||
end_section "Pre$variant"
|
||||
}
|
||||
|
||||
build()
|
||||
{
|
||||
local variant="$1"
|
||||
local build_dir="$2"
|
||||
if $build_viewer
|
||||
then
|
||||
begin_section "Viewer$variant"
|
||||
if python develop.py \
|
||||
--incredibuild \
|
||||
--unattended \
|
||||
-t $variant \
|
||||
-G "$cmake_generator" \
|
||||
build package
|
||||
# && \
|
||||
# python develop.py \
|
||||
# --incredibuild \
|
||||
# --unattended \
|
||||
# -t $variant \
|
||||
# -G "$cmake_generator" \
|
||||
# build package
|
||||
if "$AUTOBUILD" build --no-configure -c $variant
|
||||
then
|
||||
echo true >"$build_dir"/build_ok
|
||||
else
|
||||
|
|
@ -110,6 +93,7 @@ build_docs()
|
|||
end_section Docs
|
||||
}
|
||||
|
||||
|
||||
# Check to see if we were invoked from the wrapper, if not, re-exec ourselves from there
|
||||
if [ "x$arch" = x ]
|
||||
then
|
||||
|
|
@ -117,15 +101,11 @@ then
|
|||
if [ -x "$top/../buildscripts/hg/bin/build.sh" ]
|
||||
then
|
||||
exec "$top/../buildscripts/hg/bin/build.sh" "$top"
|
||||
elif [ -r "$top/README" ]
|
||||
then
|
||||
cat "$top/README"
|
||||
exit 1
|
||||
else
|
||||
cat <<EOF
|
||||
This script, if called in a development environment, requires that the branch
|
||||
independent build script repository be checked out next to this repository.
|
||||
This repository is located at http://hg.secondlife.com/buildscripts
|
||||
This repository is located at http://hg.lindenlab.com/parabuild/buildscripts
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -138,7 +118,7 @@ eval '$build_'"$arch" || pass
|
|||
# File no longer exists in code-sep branch, so let's make sure it exists in order to use it.
|
||||
if test -f scripts/update_version_files.py ; then
|
||||
begin_section UpdateVer
|
||||
scripts/update_version_files.py \
|
||||
python scripts/update_version_files.py \
|
||||
--channel="$viewer_channel" \
|
||||
--server_channel="$server_channel" \
|
||||
--revision=$revision \
|
||||
|
|
@ -149,10 +129,53 @@ fi
|
|||
|
||||
# Now retrieve the version for use in the version manager
|
||||
# First three parts only, $revision will be appended automatically.
|
||||
build_viewer_update_version_manager_version=`scripts/get_version.py --viewer-version | sed 's/\.[0-9]*$//'`
|
||||
build_viewer_update_version_manager_version=`python scripts/get_version.py --viewer-version | sed 's/\.[0-9]*$//'`
|
||||
|
||||
if [ -z "$AUTOBUILD" ]
|
||||
then
|
||||
export autobuild_dir="$here/../../../autobuild/bin/"
|
||||
if [ -d "$autobuild_dir" ]
|
||||
then
|
||||
export AUTOBUILD="$autobuild_dir"autobuild
|
||||
if [ -x "$AUTOBUILD" ]
|
||||
then
|
||||
# *HACK - bash doesn't know how to pass real pathnames to native windows python
|
||||
case "$arch" in
|
||||
CYGWIN) AUTOBUILD=$(cygpath -u $AUTOBUILD.cmd) ;;
|
||||
esac
|
||||
else
|
||||
record_failure "Not executable: $AUTOBUILD"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
record_failure "Not found: $autobuild_dir"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# load autbuild provided shell functions and variables
|
||||
# Merov: going back to the previous code that passes even if it fails catching a failure
|
||||
# TODO: use the correct code here under and fix the llbase import in python code
|
||||
#if "$AUTOBUILD" source_environment > source_environment
|
||||
#then
|
||||
# . source_environment
|
||||
#else
|
||||
# dump environment variables for debugging
|
||||
# env|sort
|
||||
# record_failure "autobuild source_environment failed"
|
||||
# cat source_environment >&3
|
||||
# exit 1
|
||||
#fi
|
||||
eval "$("$AUTOBUILD" source_environment)"
|
||||
|
||||
# dump environment variables for debugging
|
||||
env|sort
|
||||
|
||||
|
||||
# Install packages.
|
||||
"$AUTOBUILD" install --skip-license-check
|
||||
|
||||
# Now run the build
|
||||
cd indra
|
||||
succeeded=true
|
||||
build_processes=
|
||||
last_built_variant=
|
||||
|
|
@ -169,59 +192,11 @@ do
|
|||
build_dir_stubs="$build_dir/win_setup/$variant"
|
||||
rm -rf "$build_dir"
|
||||
mkdir -p "$build_dir"
|
||||
mkdir -p "$build_dir/tmp"
|
||||
#export TMP="$build_dir/tmp"
|
||||
if pre_build "$variant" "$build_dir" >> "$build_log" 2>&1
|
||||
then
|
||||
if $build_coverity
|
||||
then
|
||||
mkdir -p "$build_dir/cvbuild"
|
||||
coverity_config=`cygpath --windows "$coverity_dir/config/coverity_config.xml"`
|
||||
coverity_tmpdir=`cygpath --windows "$build_dir/cvbuild"`
|
||||
coverity_root=`cygpath --windows "$top/latest"`
|
||||
case "$variant" in
|
||||
Release)
|
||||
begin_section Coverity
|
||||
begin_section CovBuild
|
||||
"$coverity_dir"/bin/cov-build\
|
||||
--verbose 4 \
|
||||
--config "$coverity_config"\
|
||||
--dir "$coverity_tmpdir"\
|
||||
python develop.py -t $variant -G "$cmake_generator" build "$coverity_product"\
|
||||
>> "$build_log" 2>&1\
|
||||
&&\
|
||||
end_section CovBuild\
|
||||
&&\
|
||||
begin_section CovAnalyze\
|
||||
&&\
|
||||
"$coverity_dir"/bin/cov-analyze\
|
||||
--security\
|
||||
--concurrency\
|
||||
--dir "$coverity_tmpdir"\
|
||||
>> "$build_log" 2>&1\
|
||||
&&\
|
||||
end_section CovAnalyze\
|
||||
&&\
|
||||
begin_section CovCommit\
|
||||
&&\
|
||||
"$coverity_dir"/bin/cov-commit-defects\
|
||||
--stream "$coverity_product"\
|
||||
--dir "$coverity_tmpdir"\
|
||||
--host "$coverity_server"\
|
||||
--strip-path "$coverity_root"\
|
||||
--target "$branch/$arch"\
|
||||
--version "$revision"\
|
||||
--description "$repo: $variant $revision"\
|
||||
--user admin --password coverity\
|
||||
>> "$build_log" 2>&1\
|
||||
|| record_failure "Coverity Build Failed"
|
||||
# since any step could have failed, rely on the enclosing block to close any pending sub-blocks
|
||||
end_section Coverity
|
||||
;;
|
||||
esac
|
||||
if test -r "$build_dir"/cvbuild/build-log.txt
|
||||
then
|
||||
upload_item log "$build_dir"/cvbuild/build-log.txt text/plain
|
||||
fi
|
||||
elif $build_link_parallel
|
||||
if $build_link_parallel
|
||||
then
|
||||
begin_section BuildParallel
|
||||
( build "$variant" "$build_dir" > "$build_dir/build.log" 2>&1 ) &
|
||||
|
|
@ -229,10 +204,7 @@ do
|
|||
end_section BuildParallel
|
||||
else
|
||||
begin_section "Build$variant"
|
||||
build "$variant" "$build_dir" >> "$build_log" 2>&1
|
||||
begin_section Tests
|
||||
grep --line-buffered "^##teamcity" "$build_log"
|
||||
end_section Tests
|
||||
build "$variant" "$build_dir" 2>&1 | tee -a "$build_log" | grep --line-buffered "^##teamcity"
|
||||
if `cat "$build_dir/build_ok"`
|
||||
then
|
||||
echo so far so good.
|
||||
|
|
@ -261,15 +233,13 @@ then
|
|||
begin_section "Build$variant"
|
||||
build_dir=`build_dir_$arch $variant`
|
||||
build_dir_stubs="$build_dir/win_setup/$variant"
|
||||
tee -a $build_log < "$build_dir/build.log" | grep --line-buffered "^##teamcity"
|
||||
if `cat "$build_dir/build_ok"`
|
||||
then
|
||||
echo so far so good.
|
||||
else
|
||||
record_failure "Parallel build of \"$variant\" failed."
|
||||
fi
|
||||
begin_section Tests
|
||||
tee -a $build_log < "$build_dir/build.log" | grep --line-buffered "^##teamcity"
|
||||
end_section Tests
|
||||
end_section "Build$variant"
|
||||
done
|
||||
end_section WaitParallel
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
Linden Lab would like to acknowledge source code contributions from the
|
||||
following residents. The Second Life resident name is given below,
|
||||
along with the issue identifier corresponding to the patches we've
|
||||
received from them. To see more about these contributions, visit the
|
||||
browsable version: http://wiki.secondlife.com/wiki/Source_contributions
|
||||
received from them.
|
||||
|
||||
Able Whitman
|
||||
VWR-650
|
||||
|
|
@ -194,6 +193,7 @@ blino Nakamura
|
|||
VWR-17
|
||||
Boroondas Gupte
|
||||
OPEN-29
|
||||
OPEN-39
|
||||
SNOW-278
|
||||
SNOW-503
|
||||
SNOW-510
|
||||
|
|
@ -206,6 +206,7 @@ Boroondas Gupte
|
|||
VWR-20583
|
||||
VWR-20891
|
||||
VWR-23455
|
||||
VWR-24487
|
||||
WEB-262
|
||||
Bulli Schumann
|
||||
CT-218
|
||||
|
|
@ -410,9 +411,16 @@ Jonathan Yap
|
|||
VWR-17801
|
||||
VWR-24347
|
||||
STORM-975
|
||||
STORM-990
|
||||
STORM-1019
|
||||
STORM-844
|
||||
STORM-643
|
||||
STORM-1020
|
||||
STORM-1064
|
||||
STORM-960
|
||||
STORM-1108
|
||||
STORM-1094
|
||||
STORM-1077
|
||||
STORM-953
|
||||
Kage Pixel
|
||||
VWR-11
|
||||
Ken March
|
||||
|
|
@ -434,6 +442,8 @@ Kitty Barnett
|
|||
Kunnis Basiat
|
||||
VWR-82
|
||||
VWR-102
|
||||
Lance Corrimal
|
||||
VWR-25269
|
||||
Latif Khalifa
|
||||
VWR-5370
|
||||
Lisa Lowe
|
||||
|
|
@ -573,6 +583,10 @@ Nicholaz Beresford
|
|||
VWR-2412
|
||||
VWR-2682
|
||||
VWR-2684
|
||||
Nicky Perian
|
||||
OPEN-1
|
||||
OPEN-1087
|
||||
STORM-1090
|
||||
Nounouch Hapmouche
|
||||
VWR-238
|
||||
Patric Mills
|
||||
|
|
@ -642,6 +656,7 @@ Robin Cornelius
|
|||
SNOW-747
|
||||
STORM-422
|
||||
STORM-960
|
||||
STORM-1019
|
||||
VWR-2488
|
||||
VWR-9557
|
||||
VWR-10579
|
||||
|
|
@ -778,6 +793,7 @@ Thickbrick Sleaford
|
|||
VWR-13483
|
||||
VWR-13947
|
||||
VWR-24420
|
||||
STORM-1147
|
||||
Thraxis Epsilon
|
||||
SVC-371
|
||||
VWR-383
|
||||
|
|
@ -836,6 +852,8 @@ Whoops Babii
|
|||
Wilton Lundquist
|
||||
VWR-7682
|
||||
WolfPup Lowenhar
|
||||
OPEN-1
|
||||
OPEN-37
|
||||
SNOW-622
|
||||
SNOW-772
|
||||
STORM-102
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ if (VIEWER)
|
|||
endif (VIEWER)
|
||||
|
||||
# Linux builds the viewer and server in 2 separate projects
|
||||
# In order for ./develop.py build server to work on linux,
|
||||
# In order for build server to work on linux,
|
||||
# the viewer project needs a server target.
|
||||
# This is not true for mac and windows.
|
||||
if (LINUX)
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ include(Variables)
|
|||
# Portable compilation flags.
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DNDEBUG")
|
||||
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DNDEBUG")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"-DLL_RELEASE=1 -D_SECURE_SCL=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
|
||||
"-DLL_RELEASE=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
|
||||
|
||||
# Configure crash reporting
|
||||
set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
|
||||
|
|
@ -36,13 +36,13 @@ if (WINDOWS)
|
|||
# Don't build DLLs.
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP"
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP -D_SCL_SECURE_NO_WARNINGS=1"
|
||||
CACHE STRING "C++ compiler debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /Ob2"
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /Ob2 -D_SECURE_STL=0"
|
||||
CACHE STRING "C++ compiler release-with-debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2"
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||
CACHE STRING "C++ compiler release options" FORCE)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "")
|
||||
|
|
@ -59,18 +59,9 @@ if (WINDOWS)
|
|||
/Zc:forScope
|
||||
/nologo
|
||||
/Oy-
|
||||
)
|
||||
|
||||
if(MSVC80 OR MSVC90)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||
CACHE STRING "C++ compiler release options" FORCE)
|
||||
|
||||
add_definitions(
|
||||
/Zc:wchar_t-
|
||||
)
|
||||
endif (MSVC80 OR MSVC90)
|
||||
|
||||
|
||||
# Are we using the crummy Visual Studio KDU build workaround?
|
||||
if (NOT VS_DISABLE_FATAL_WARNINGS)
|
||||
add_definitions(/WX)
|
||||
|
|
|
|||
|
|
@ -32,27 +32,21 @@ else (STANDALONE)
|
|||
)
|
||||
elseif (DARWIN)
|
||||
if (LLCOMMON_LINK_SHARED)
|
||||
set(APR_selector "0.3.7.dylib")
|
||||
set(APRUTIL_selector "0.3.8.dylib")
|
||||
set(APR_selector "0.dylib")
|
||||
set(APRUTIL_selector "0.dylib")
|
||||
else (LLCOMMON_LINK_SHARED)
|
||||
set(APR_selector "a")
|
||||
set(APRUTIL_selector "a")
|
||||
endif (LLCOMMON_LINK_SHARED)
|
||||
set(APR_LIBRARIES
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.${APR_selector}
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.${APR_selector}
|
||||
)
|
||||
set(APRUTIL_LIBRARIES
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.${APRUTIL_selector}
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.${APRUTIL_selector}
|
||||
)
|
||||
set(APR_LIBRARIES libapr-1.${APR_selector})
|
||||
set(APRUTIL_LIBRARIES libaprutil-1.${APRUTIL_selector})
|
||||
set(APRICONV_LIBRARIES iconv)
|
||||
else (WINDOWS)
|
||||
set(APR_LIBRARIES apr-1)
|
||||
set(APRUTIL_LIBRARIES aprutil-1)
|
||||
set(APRICONV_LIBRARIES iconv)
|
||||
endif (WINDOWS)
|
||||
set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/apr-1)
|
||||
set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)
|
||||
|
||||
if (LINUX)
|
||||
if (VIEWER)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ if (STANDALONE)
|
|||
else (STANDALONE)
|
||||
if (LINUX)
|
||||
# Need to add dependency pthread explicitely to support ld.gold.
|
||||
set(DB_LIBRARIES db-4.2 pthread)
|
||||
use_prebuilt_binary(db)
|
||||
set(DB_LIBRARIES db-5.1 pthread)
|
||||
else (LINUX)
|
||||
set(DB_LIBRARIES db-4.2)
|
||||
endif (LINUX)
|
||||
|
|
|
|||
|
|
@ -10,23 +10,15 @@ if (STANDALONE)
|
|||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex-mt)
|
||||
set(BOOST_SIGNALS_LIBRARY boost_signals-mt)
|
||||
set(BOOST_SYSTEM_LIBRARY boost_system-mt)
|
||||
set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(boost)
|
||||
set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
|
||||
if (WINDOWS)
|
||||
set(BOOST_VERSION 1_39)
|
||||
if (MSVC71)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY
|
||||
optimized libboost_program_options-vc71-mt-s-${BOOST_VERSION}
|
||||
debug libboost_program_options-vc71-mt-sgd-${BOOST_VERSION})
|
||||
set(BOOST_REGEX_LIBRARY
|
||||
optimized libboost_regex-vc71-mt-s-${BOOST_VERSION}
|
||||
debug libboost_regex-vc71-mt-sgd-${BOOST_VERSION})
|
||||
set(BOOST_SIGNALS_LIBRARY
|
||||
optimized libboost_signals-vc71-mt-s-${BOOST_VERSION}
|
||||
debug libboost_signals-vc71-mt-sgd-${BOOST_VERSION})
|
||||
else (MSVC71)
|
||||
set(BOOST_VERSION 1_45)
|
||||
if(MSVC80)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY
|
||||
optimized libboost_program_options-vc80-mt-${BOOST_VERSION}
|
||||
debug libboost_program_options-vc80-mt-gd-${BOOST_VERSION})
|
||||
|
|
@ -36,14 +28,31 @@ else (STANDALONE)
|
|||
set(BOOST_SIGNALS_LIBRARY
|
||||
optimized libboost_signals-vc80-mt-${BOOST_VERSION}
|
||||
debug libboost_signals-vc80-mt-gd-${BOOST_VERSION})
|
||||
endif (MSVC71)
|
||||
elseif (DARWIN)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-xgcc40-mt)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex-xgcc40-mt)
|
||||
set(BOOST_SIGNALS_LIBRARY boost_signals-xgcc40-mt)
|
||||
elseif (LINUX)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-gcc41-mt)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex-gcc41-mt)
|
||||
set(BOOST_SIGNALS_LIBRARY boost_signals-gcc41-mt)
|
||||
set(BOOST_SYSTEM_LIBRARY
|
||||
optimized libboost_system-vc80-mt-${BOOST_VERSION}
|
||||
debug libboost_system-vc80-mt-gd-${BOOST_VERSION})
|
||||
set(BOOST_FILESYSTEM_LIBRARY
|
||||
optimized libboost_filesystem-vc80-mt-${BOOST_VERSION}
|
||||
debug libboost_filesystem-vc80-mt-gd-${BOOST_VERSION})
|
||||
else(MSVC80)
|
||||
# MSVC 10.0 config
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY
|
||||
optimized libboost_program_options-vc100-mt-${BOOST_VERSION}
|
||||
debug libboost_program_options-vc100-mt-gd-${BOOST_VERSION})
|
||||
set(BOOST_REGEX_LIBRARY
|
||||
optimized libboost_regex-vc100-mt-${BOOST_VERSION}
|
||||
debug libboost_regex-vc100-mt-gd-${BOOST_VERSION})
|
||||
set(BOOST_SYSTEM_LIBRARY
|
||||
optimized libboost_system-vc100-mt-${BOOST_VERSION}
|
||||
debug libboost_system-vc100-mt-gd-${BOOST_VERSION})
|
||||
set(BOOST_FILESYSTEM_LIBRARY
|
||||
optimized libboost_filesystem-vc100-mt-${BOOST_VERSION}
|
||||
debug libboost_filesystem-vc100-mt-gd-${BOOST_VERSION})
|
||||
endif (MSVC80)
|
||||
elseif (DARWIN OR LINUX)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex)
|
||||
set(BOOST_SYSTEM_LIBRARY boost_system)
|
||||
set(BOOST_FILESYSTEM_LIBRARY boost_filesystem)
|
||||
endif (WINDOWS)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,7 @@ else (STANDALONE)
|
|||
if (WINDOWS)
|
||||
set(CARES_LIBRARIES areslib)
|
||||
elseif (DARWIN)
|
||||
set(CARES_LIBRARIES
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libcares.a
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libcares.a
|
||||
)
|
||||
set(CARES_LIBRARIES cares)
|
||||
else (WINDOWS)
|
||||
set(CARES_LIBRARIES cares)
|
||||
endif (WINDOWS)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ set(cmake_SOURCE_FILES
|
|||
CSharpMacros.cmake
|
||||
DBusGlib.cmake
|
||||
DirectX.cmake
|
||||
ELFIO.cmake
|
||||
EXPAT.cmake
|
||||
FindAPR.cmake
|
||||
FindBerkeleyDB.cmake
|
||||
|
|
@ -29,7 +28,6 @@ set(cmake_SOURCE_FILES
|
|||
FindFMOD.cmake
|
||||
FindGooglePerfTools.cmake
|
||||
FindMono.cmake
|
||||
FindMT.cmake
|
||||
FindMySQL.cmake
|
||||
FindOpenJPEG.cmake
|
||||
FindXmlRpcEpi.cmake
|
||||
|
|
@ -85,7 +83,6 @@ source_group("Shared Rules" FILES ${cmake_SOURCE_FILES})
|
|||
|
||||
set(master_SOURCE_FILES
|
||||
../CMakeLists.txt
|
||||
../develop.py
|
||||
)
|
||||
|
||||
if (SERVER)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
# VisualStudio.
|
||||
|
||||
include(CMakeCopyIfDifferent)
|
||||
include(Linking)
|
||||
|
||||
###################################################################
|
||||
# set up platform specific lists of files that need to be copied
|
||||
|
|
@ -16,7 +17,7 @@ if(WINDOWS)
|
|||
|
||||
#*******************************
|
||||
# VIVOX - *NOTE: no debug version
|
||||
set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-win32")
|
||||
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
set(vivox_files
|
||||
SLVoice.exe
|
||||
libsndfile-1.dll
|
||||
|
|
@ -30,24 +31,24 @@ if(WINDOWS)
|
|||
#*******************************
|
||||
# Misc shared libs
|
||||
|
||||
# *TODO - update this to use LIBS_PREBUILT_DIR and LL_ARCH_DIR variables
|
||||
# or ARCH_PREBUILT_DIRS
|
||||
set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug")
|
||||
set(debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}")
|
||||
set(debug_files
|
||||
openjpegd.dll
|
||||
libapr-1.dll
|
||||
libaprutil-1.dll
|
||||
libapriconv-1.dll
|
||||
ssleay32.dll
|
||||
libeay32.dll
|
||||
)
|
||||
|
||||
# *TODO - update this to use LIBS_PREBUILT_DIR and LL_ARCH_DIR variables
|
||||
# or ARCH_PREBUILT_DIRS
|
||||
set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release")
|
||||
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
set(release_files
|
||||
openjpeg.dll
|
||||
libapr-1.dll
|
||||
libaprutil-1.dll
|
||||
libapriconv-1.dll
|
||||
ssleay32.dll
|
||||
libeay32.dll
|
||||
)
|
||||
|
||||
if(USE_GOOGLE_PERFTOOLS)
|
||||
|
|
@ -121,6 +122,62 @@ if (MSVC80)
|
|||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
endif (EXISTS ${release_msvc8_redist_path})
|
||||
elseif (MSVC_VERSION EQUAL 1600) # VisualStudio 2010
|
||||
FIND_PATH(debug_msvc10_redist_path msvcr100d.dll
|
||||
PATHS
|
||||
${MSVC_DEBUG_REDIST_PATH}
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/redist/Debug_NonRedist/x86/Microsoft.VC100.DebugCRT
|
||||
NO_DEFAULT_PATH
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
if(EXISTS ${debug_msvc10_redist_path})
|
||||
set(debug_msvc10_files
|
||||
msvcr100d.dll
|
||||
msvcp100d.dll
|
||||
)
|
||||
|
||||
copy_if_different(
|
||||
${debug_msvc10_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_DEBUG}"
|
||||
out_targets
|
||||
${debug_msvc10_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
endif ()
|
||||
|
||||
FIND_PATH(release_msvc10_redist_path msvcr100.dll
|
||||
PATHS
|
||||
${MSVC_REDIST_PATH}
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/redist/x86/Microsoft.VC100.CRT
|
||||
NO_DEFAULT_PATH
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
if(EXISTS ${release_msvc10_redist_path})
|
||||
set(release_msvc10_files
|
||||
msvcr100.dll
|
||||
msvcp100.dll
|
||||
)
|
||||
|
||||
copy_if_different(
|
||||
${release_msvc10_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_RELEASE}"
|
||||
out_targets
|
||||
${release_msvc10_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
copy_if_different(
|
||||
${release_msvc10_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}"
|
||||
out_targets
|
||||
${release_msvc10_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
endif ()
|
||||
endif (MSVC80)
|
||||
|
||||
elseif(DARWIN)
|
||||
|
|
@ -128,7 +185,7 @@ elseif(DARWIN)
|
|||
set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/Resources")
|
||||
set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}/Release/Resources")
|
||||
|
||||
set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/universal-darwin")
|
||||
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
set(vivox_files
|
||||
SLVoice
|
||||
libsndfile.dylib
|
||||
|
|
@ -137,20 +194,16 @@ elseif(DARWIN)
|
|||
libvivoxplatform.dylib
|
||||
libvivoxsdk.dylib
|
||||
)
|
||||
# *TODO - update this to use LIBS_PREBUILT_DIR and LL_ARCH_DIR variables
|
||||
# or ARCH_PREBUILT_DIRS
|
||||
set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_debug")
|
||||
set(debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}")
|
||||
set(debug_files
|
||||
)
|
||||
# *TODO - update this to use LIBS_PREBUILT_DIR and LL_ARCH_DIR variables
|
||||
# or ARCH_PREBUILT_DIRS
|
||||
set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release")
|
||||
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
set(release_files
|
||||
libapr-1.0.3.7.dylib
|
||||
libapr-1.0.dylib
|
||||
libapr-1.dylib
|
||||
libaprutil-1.0.3.8.dylib
|
||||
libaprutil-1.0.dylib
|
||||
libaprutil-1.dylib
|
||||
libexpat.0.5.0.dylib
|
||||
libexpat.1.5.2.dylib
|
||||
libexpat.dylib
|
||||
libllqtwebkit.dylib
|
||||
libndofdev.dylib
|
||||
|
|
@ -167,7 +220,7 @@ elseif(LINUX)
|
|||
set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}")
|
||||
set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}")
|
||||
|
||||
set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-linux")
|
||||
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
set(vivox_files
|
||||
libsndfile.so.1
|
||||
libortp.so
|
||||
|
|
@ -178,20 +231,20 @@ elseif(LINUX)
|
|||
)
|
||||
# *TODO - update this to use LIBS_PREBUILT_DIR and LL_ARCH_DIR variables
|
||||
# or ARCH_PREBUILT_DIRS
|
||||
set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-linux/lib_debug")
|
||||
set(debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}")
|
||||
set(debug_files
|
||||
)
|
||||
# *TODO - update this to use LIBS_PREBUILT_DIR and LL_ARCH_DIR variables
|
||||
# or ARCH_PREBUILT_DIRS
|
||||
set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-linux/lib_release_client")
|
||||
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
# *FIX - figure out what to do with duplicate libalut.so here -brad
|
||||
set(release_files
|
||||
libapr-1.so.0
|
||||
libaprutil-1.so.0
|
||||
libatk-1.0.so
|
||||
libbreakpad_client.so.0
|
||||
libcrypto.so.0.9.7
|
||||
libdb-4.2.so
|
||||
libcrypto.so.0.9.8
|
||||
libdb-5.1.so
|
||||
libexpat.so
|
||||
libexpat.so.1
|
||||
libgmock_main.so
|
||||
|
|
@ -203,10 +256,11 @@ elseif(LINUX)
|
|||
libopenal.so
|
||||
libopenjpeg.so
|
||||
libssl.so
|
||||
libstacktrace.so
|
||||
libtcmalloc.so
|
||||
libuuid.so.1
|
||||
libssl.so.0.9.7
|
||||
libuuid.so.16
|
||||
libuuid.so.16.0.22
|
||||
libssl.so.0.9.8
|
||||
libfontconfig.so.1.4.4
|
||||
)
|
||||
|
||||
if (FMOD)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ elseif (LINUX)
|
|||
use_prebuilt_binary(dbusglib)
|
||||
set(DBUSGLIB_FOUND ON FORCE BOOL)
|
||||
set(DBUSGLIB_INCLUDE_DIRS
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0
|
||||
${LIBS_PREBUILT_DIR}/include/dbus
|
||||
)
|
||||
# We don't need to explicitly link against dbus-glib itself, because
|
||||
# the viewer probes for the system's copy at runtime.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
if (VIEWER AND WINDOWS)
|
||||
find_path(DIRECTX_INCLUDE_DIR dxdiag.h
|
||||
"$ENV{DXSDK_DIR}/Include"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Include"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Include"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2008)/Include"
|
||||
|
|
@ -24,6 +25,7 @@ if (VIEWER AND WINDOWS)
|
|||
|
||||
find_path(DIRECTX_LIBRARY_DIR dxguid.lib
|
||||
"$ENV{DXSDK_DIR}/Lib/x86"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Lib/x86"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Lib/x86"
|
||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2008)/Lib/x86"
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
set(ELFIO_FIND_QUIETLY ON)
|
||||
|
||||
if (STANDALONE)
|
||||
include(FindELFIO)
|
||||
elseif (LINUX)
|
||||
use_prebuilt_binary(elfio)
|
||||
set(ELFIO_LIBRARIES ELFIO)
|
||||
set(ELFIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
set(ELFIO_FOUND "YES")
|
||||
endif (STANDALONE)
|
||||
|
||||
if (ELFIO_FOUND)
|
||||
add_definitions(-DLL_ELFBIN=1)
|
||||
else (ELFIO_FOUND)
|
||||
set(ELFIO_INCLUDE_DIR "")
|
||||
endif (ELFIO_FOUND)
|
||||
|
|
@ -1,26 +1,39 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
set(FMOD ON CACHE BOOL "Use FMOD sound library.")
|
||||
# FMOD can be set when launching the make using the argument -DFMOD:BOOL=ON
|
||||
# When building using proprietary binaries though (i.e. having access to LL private servers),
|
||||
# we always build with FMOD.
|
||||
# Open source devs should use the -DFMOD:BOOL=ON then if they want to build with FMOD, whether
|
||||
# they are using STANDALONE or not.
|
||||
if (INSTALL_PROPRIETARY)
|
||||
set(FMOD ON CACHE BOOL "Use FMOD sound library.")
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
|
||||
if (FMOD)
|
||||
if (STANDALONE)
|
||||
# In that case, we use the version of the library installed on the system
|
||||
set(FMOD_FIND_REQUIRED ON)
|
||||
include(FindFMOD)
|
||||
else (STANDALONE)
|
||||
if (INSTALL_PROPRIETARY)
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(fmod)
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
|
||||
if (WINDOWS)
|
||||
set(FMOD_LIBRARY fmod)
|
||||
elseif (DARWIN)
|
||||
set(FMOD_LIBRARY fmod)
|
||||
elseif (LINUX)
|
||||
set(FMOD_LIBRARY fmod-3.75)
|
||||
endif (WINDOWS)
|
||||
|
||||
SET(FMOD_LIBRARIES ${FMOD_LIBRARY})
|
||||
set(FMOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
if (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
|
||||
# If the path have been specified in the arguments, use that
|
||||
set(FMOD_LIBRARIES ${FMOD_LIBRARY})
|
||||
MESSAGE(STATUS "Using FMOD path: ${FMOD_LIBRARIES}, ${FMOD_INCLUDE_DIR}")
|
||||
else (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
|
||||
# If not, we're going to try to get the package listed in autobuild.xml
|
||||
# Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL)
|
||||
# as accessing the private LL location will fail if you don't have the credential
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(fmod)
|
||||
if (WINDOWS)
|
||||
set(FMOD_LIBRARY fmod)
|
||||
elseif (DARWIN)
|
||||
set(FMOD_LIBRARY fmod)
|
||||
elseif (LINUX)
|
||||
set(FMOD_LIBRARY fmod-3.75)
|
||||
endif (WINDOWS)
|
||||
set(FMOD_LIBRARIES ${FMOD_LIBRARY})
|
||||
set(FMOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
|
||||
endif (STANDALONE)
|
||||
endif (FMOD)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
# -*- cmake -*-
|
||||
#
|
||||
# Find the autobuild tool
|
||||
#
|
||||
# Output variables:
|
||||
#
|
||||
# AUTOBUILD_EXECUTABLE - path to autobuild or pautobuild executable
|
||||
|
||||
# *TODO - if cmake was executed by autobuild, autobuild will have set the AUTOBUILD env var
|
||||
# update this to check for that case
|
||||
|
||||
IF (NOT AUTOBUILD_EXECUTABLE)
|
||||
IF(WIN32)
|
||||
SET(AUTOBUILD_EXE_NAMES autobuild.cmd autobuild.exe)
|
||||
ELSE(WIN32)
|
||||
SET(AUTOBUILD_EXE_NAMES autobuild)
|
||||
ENDIF(WIN32)
|
||||
|
||||
SET(AUTOBUILD_EXECUTABLE)
|
||||
FIND_PROGRAM(
|
||||
AUTOBUILD_EXECUTABLE
|
||||
NAMES ${AUTOBUILD_EXE_NAMES}
|
||||
PATHS
|
||||
ENV PATH
|
||||
${CMAKE_SOURCE_DIR}/..
|
||||
${CMAKE_SOURCE_DIR}/../..
|
||||
${CMAKE_SOURCE_DIR}/../../..
|
||||
PATH_SUFFIXES "/autobuild/bin/"
|
||||
)
|
||||
|
||||
IF (AUTOBUILD_EXECUTABLE)
|
||||
GET_FILENAME_COMPONENT(_autobuild_name ${AUTOBUILD_EXECUTABLE} NAME_WE)
|
||||
MESSAGE(STATUS "Using autobuild at: ${AUTOBUILD_EXECUTABLE}")
|
||||
ELSE (AUTOBUILD_EXECUTABLE)
|
||||
IF (AUTOBUILD_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find autobuild executable")
|
||||
ENDIF (AUTOBUILD_FIND_REQUIRED)
|
||||
ENDIF (AUTOBUILD_EXECUTABLE)
|
||||
|
||||
MARK_AS_ADVANCED(AUTOBUILD_EXECUTABLE)
|
||||
ENDIF (NOT AUTOBUILD_EXECUTABLE)
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
FIND_PATH(FMOD_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod)
|
||||
|
||||
SET(FMOD_NAMES ${FMOD_NAMES} fmod fmodvc fmod-3.75)
|
||||
SET(FMOD_NAMES ${FMOD_NAMES} fmod fmodvc fmodex fmod-3.75)
|
||||
FIND_LIBRARY(FMOD_LIBRARY
|
||||
NAMES ${FMOD_NAMES}
|
||||
PATH_SUFFIXES fmod
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ else (STANDALONE)
|
|||
use_prebuilt_binary(freetype)
|
||||
if (LINUX)
|
||||
set(FREETYPE_INCLUDE_DIRS
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
${LIBS_PREBUILT_DIR}/include)
|
||||
else (LINUX)
|
||||
set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (LINUX)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ elseif (LINUX)
|
|||
set(GSTREAMER010_FOUND ON FORCE BOOL)
|
||||
set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL)
|
||||
set(GSTREAMER010_INCLUDE_DIRS
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2
|
||||
${LIBS_PREBUILT_DIR}/include/gstreamer-0.10
|
||||
${LIBS_PREBUILT_DIR}/include/glib-2.0
|
||||
${LIBS_PREBUILT_DIR}/include/libxml2
|
||||
)
|
||||
# We don't need to explicitly link against gstreamer itself, because
|
||||
# LLMediaImplGStreamer probes for the system's copy at runtime.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ include(Prebuilt)
|
|||
if (STANDALONE)
|
||||
include(FindGooglePerfTools)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(google)
|
||||
if (WINDOWS)
|
||||
use_prebuilt_binary(google-perftools)
|
||||
set(TCMALLOC_LIBRARIES
|
||||
|
|
@ -13,11 +12,11 @@ else (STANDALONE)
|
|||
set(GOOGLE_PERFTOOLS_FOUND "YES")
|
||||
endif (WINDOWS)
|
||||
if (LINUX)
|
||||
use_prebuilt_binary(google-perftools)
|
||||
set(TCMALLOC_LIBRARIES tcmalloc)
|
||||
set(STACKTRACE_LIBRARIES stacktrace)
|
||||
set(PROFILER_LIBRARIES profiler)
|
||||
set(GOOGLE_PERFTOOLS_INCLUDE_DIR
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
${LIBS_PREBUILT_DIR}/include)
|
||||
set(GOOGLE_PERFTOOLS_FOUND "YES")
|
||||
endif (LINUX)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -12,10 +12,7 @@ else (STANDALONE)
|
|||
if (LINUX)
|
||||
set(JPEG_LIBRARIES jpeg)
|
||||
elseif (DARWIN)
|
||||
set(JPEG_LIBRARIES
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/liblljpeg.a
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/liblljpeg.a
|
||||
)
|
||||
set(JPEG_LIBRARIES jpeg)
|
||||
elseif (WINDOWS)
|
||||
set(JPEG_LIBRARIES jpeglib)
|
||||
endif (LINUX)
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ else (STANDALONE)
|
|||
use_prebuilt_binary(jsoncpp)
|
||||
if (WINDOWS)
|
||||
set(JSONCPP_LIBRARIES
|
||||
debug json_vc80d
|
||||
optimized json_vc80)
|
||||
debug json_vc100debug_libmt.lib
|
||||
optimized json_vc100_libmt)
|
||||
elseif (DARWIN)
|
||||
set(JSONCPP_LIBRARIES json_mac-universal-gcc_libmt)
|
||||
set(JSONCPP_LIBRARIES libjson_linux-gcc-4.0.1_libmt.a)
|
||||
elseif (LINUX)
|
||||
set(JSONCPP_LIBRARIES jsoncpp)
|
||||
set(JSONCPP_LIBRARIES libjson_linux-gcc-4.1.3_libmt.a)
|
||||
endif (WINDOWS)
|
||||
set(JSONCPP_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/jsoncpp)
|
||||
set(JSONCPP_INCLUDE_DIRS "${LIBS_PREBUILT_DIR}/include/jsoncpp" "${LIBS_PREBUILT_DIR}/include/json")
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# -*- cmake -*-
|
||||
include(LLTestCommand)
|
||||
include(GoogleMock)
|
||||
include(Tut)
|
||||
|
||||
MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
||||
# Given a project name and a list of sourcefiles (with optional properties on each),
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
# USE_KDU can be set when launching cmake or develop.py as an option using the argument -DUSE_KDU:BOOL=ON
|
||||
# When building using proprietary binaries though (i.e. having access to LL private servers), we always build with KDU
|
||||
if (INSTALL_PROPRIETARY AND NOT STANDALONE)
|
||||
set(USE_KDU ON)
|
||||
endif (INSTALL_PROPRIETARY AND NOT STANDALONE)
|
||||
# USE_KDU can be set when launching cmake as an option using the argument -DUSE_KDU:BOOL=ON
|
||||
# When building using proprietary binaries though (i.e. having access to LL private servers),
|
||||
# we always build with KDU
|
||||
if (INSTALL_PROPRIETARY)
|
||||
set(USE_KDU ON CACHE BOOL "Use Kakadu library.")
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
|
||||
if (USE_KDU)
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(kdu)
|
||||
if (WINDOWS)
|
||||
set(KDU_LIBRARY kdu.lib)
|
||||
else (WINDOWS)
|
||||
set(KDU_LIBRARY libkdu.a)
|
||||
endif (WINDOWS)
|
||||
set(KDU_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/kdu)
|
||||
set(KDU_INCLUDE_DIR ${AUTOBUILD_INSTALL_DIR}/include/kdu)
|
||||
set(LLKDU_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llkdu)
|
||||
set(LLKDU_LIBRARIES llkdu)
|
||||
endif (USE_KDU)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ else (STANDALONE)
|
|||
use_prebuilt_binary(SDL)
|
||||
set (SDL_FOUND TRUE)
|
||||
set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux)
|
||||
set (SDL_LIBRARY SDL)
|
||||
set (SDL_LIBRARY SDL directfb fusion direct)
|
||||
endif (LINUX AND VIEWER)
|
||||
endif (STANDALONE)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +1,43 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
include(Variables)
|
||||
|
||||
|
||||
if (NOT STANDALONE)
|
||||
set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib)
|
||||
set(ARCH_PREBUILT_DIRS_RELEASE ${AUTOBUILD_INSTALL_DIR}/lib/release)
|
||||
set(ARCH_PREBUILT_DIRS_DEBUG ${AUTOBUILD_INSTALL_DIR}/lib/debug)
|
||||
if (WINDOWS)
|
||||
set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib)
|
||||
set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/release)
|
||||
set(ARCH_PREBUILT_DIRS_DEBUG ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/debug)
|
||||
set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs CACHE FILEPATH "Location of staged DLLs")
|
||||
set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs CACHE FILEPATH "Location of staged executables")
|
||||
set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs)
|
||||
set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs)
|
||||
elseif (LINUX)
|
||||
if (VIEWER)
|
||||
set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib_release_client)
|
||||
else (VIEWER)
|
||||
set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib_release)
|
||||
endif (VIEWER)
|
||||
set(ARCH_PREBUILT_DIRS_RELEASE ${ARCH_PREBUILT_DIRS})
|
||||
set(ARCH_PREBUILT_DIRS_DEBUG ${ARCH_PREBUILT_DIRS})
|
||||
set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/lib CACHE FILEPATH "Location of staged .sos")
|
||||
set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/bin CACHE FILEPATH "Location of staged executables")
|
||||
set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/lib)
|
||||
set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/bin)
|
||||
elseif (DARWIN)
|
||||
set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib_release)
|
||||
set(ARCH_PREBUILT_DIRS ${ARCH_PREBUILT_DIRS_RELEASE})
|
||||
set(ARCH_PREBUILT_DIRS_DEBUG ${ARCH_PREBUILT_DIRS_RELEASE})
|
||||
set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs CACHE FILEPATH "Location of staged DLLs")
|
||||
set(EXE_STAGING_DIR "${CMAKE_BINARY_DIR}/sharedlibs/\$(CONFIGURATION)" CACHE FILEPATH "Location of staged executables")
|
||||
set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs)
|
||||
set(EXE_STAGING_DIR "${CMAKE_BINARY_DIR}/sharedlibs/\$(CONFIGURATION)")
|
||||
endif (WINDOWS)
|
||||
endif (NOT STANDALONE)
|
||||
|
||||
link_directories(${ARCH_PREBUILT_DIRS})
|
||||
# Autobuild packages must provide 'release' versions of libraries, but may provide versions for
|
||||
# specific build types. AUTOBUILD_LIBS_INSTALL_DIRS lists first the build type directory and then
|
||||
# the 'release' directory (as a default fallback).
|
||||
# *NOTE - we have to take special care to use CMAKE_CFG_INTDIR on IDE generators (like mac and
|
||||
# windows) and CMAKE_BUILD_TYPE on Makefile based generators (like linux). The reason for this is
|
||||
# that CMAKE_BUILD_TYPE is essentially meaningless at configuration time for IDE generators and
|
||||
# CMAKE_CFG_INTDIR is meaningless at build time for Makefile generators
|
||||
if(WINDOWS OR DARWIN)
|
||||
# the cmake xcode and VS generators implicitly append ${CMAKE_CFG_INTDIR} to the library paths for us
|
||||
# fortunately both windows and darwin are case insensitive filesystems so this works.
|
||||
set(AUTOBUILD_LIBS_INSTALL_DIRS "${AUTOBUILD_INSTALL_DIR}/lib/")
|
||||
else(WINDOWS OR DARWIN)
|
||||
# else block is for linux and any other makefile based generators
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
|
||||
set(AUTOBUILD_LIBS_INSTALL_DIRS ${AUTOBUILD_INSTALL_DIR}/lib/${CMAKE_BUILD_TYPE_LOWER})
|
||||
endif(WINDOWS OR DARWIN)
|
||||
|
||||
list(APPEND AUTOBUILD_LIBS_INSTALL_DIRS ${ARCH_PREBUILT_DIRS_RELEASE})
|
||||
link_directories(${AUTOBUILD_LIBS_INSTALL_DIRS})
|
||||
|
||||
if (LINUX)
|
||||
set(DL_LIBRARY dl)
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ IF (DARWIN)
|
|||
|
||||
ELSE (DARWIN)
|
||||
|
||||
SET(MONO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
SET(MONO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
SET(GLIB_2_0_PLATFORM_INCLUDE_DIR
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0)
|
||||
${LIBS_PREBUILT_DIR}/include/glib-2.0)
|
||||
SET(GLIB_2_0_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/glib-2.0)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use_prebuilt_binary(mysql)
|
|||
if (LINUX)
|
||||
if (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
|
||||
set(MYSQL_LIBRARIES mysqlclient)
|
||||
set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
else (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
|
||||
# Use the native MySQL library on a 64-bit system.
|
||||
set(MYSQL_FIND_QUIETLY ON)
|
||||
|
|
@ -16,9 +16,9 @@ if (LINUX)
|
|||
endif (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
|
||||
elseif (WINDOWS)
|
||||
set(MYSQL_LIBRARIES mysqlclient)
|
||||
set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
elseif (DARWIN)
|
||||
set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
set(MYSQL_LIBRARIES
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libmysqlclient.a
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libmysqlclient.a
|
||||
|
|
|
|||
|
|
@ -9,18 +9,26 @@ else (LINUX)
|
|||
endif (LINUX)
|
||||
|
||||
if (OPENAL)
|
||||
set(OPENAL_LIB_INCLUDE_DIRS "${LIBS_PREBUILT_DIR}/include/AL")
|
||||
if (STANDALONE)
|
||||
include(FindPkgConfig)
|
||||
include(FindOpenAL)
|
||||
pkg_check_modules(OPENAL_LIB REQUIRED openal)
|
||||
pkg_check_modules(FREEALUT_LIB REQUIRED freealut)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(openal-soft)
|
||||
use_prebuilt_binary(openal_soft)
|
||||
endif (STANDALONE)
|
||||
set(OPENAL_LIBRARIES
|
||||
openal
|
||||
alut
|
||||
if(WINDOWS)
|
||||
set(OPENAL_LIBRARIES
|
||||
OpenAL32
|
||||
alut
|
||||
)
|
||||
else()
|
||||
set(OPENAL_LIBRARIES
|
||||
openal
|
||||
alut
|
||||
)
|
||||
endif()
|
||||
endif (OPENAL)
|
||||
|
||||
if (OPENAL)
|
||||
|
|
|
|||
|
|
@ -5,5 +5,5 @@ if (NOT STANDALONE)
|
|||
use_prebuilt_binary(GL)
|
||||
# possible glh_linear should have its own .cmake file instead
|
||||
use_prebuilt_binary(glh_linear)
|
||||
set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (NOT STANDALONE)
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ else (STANDALONE)
|
|||
else (WINDOWS)
|
||||
set(OPENSSL_LIBRARIES ssl)
|
||||
endif (WINDOWS)
|
||||
set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (STANDALONE)
|
||||
|
||||
if (LINUX)
|
||||
set(CRYPTO_LIBRARIES crypto)
|
||||
elseif (DARWIN)
|
||||
set(CRYPTO_LIBRARIES llcrypto)
|
||||
set(CRYPTO_LIBRARIES crypto)
|
||||
endif (LINUX)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,14 @@ if (STANDALONE)
|
|||
include(FindPNG)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(libpng)
|
||||
set(PNG_LIBRARIES png12)
|
||||
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng12)
|
||||
if (WINDOWS)
|
||||
set(PNG_LIBRARIES libpng15)
|
||||
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng15)
|
||||
elseif(DARWIN)
|
||||
set(PNG_LIBRARIES png15)
|
||||
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng15)
|
||||
else()
|
||||
set(PNG_LIBRARIES png15)
|
||||
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng15)
|
||||
endif()
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -1,36 +1,31 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
include(Python)
|
||||
include(FindSCP)
|
||||
include(FindAutobuild)
|
||||
|
||||
macro (use_prebuilt_binary _binary)
|
||||
if (NOT STANDALONE)
|
||||
if (NOT DEFINED STANDALONE_${_binary})
|
||||
set(STANDALONE_${_binary} ${STANDALONE})
|
||||
endif (NOT DEFINED STANDALONE_${_binary})
|
||||
|
||||
if (NOT STANDALONE_${_binary})
|
||||
if(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
|
||||
if(INSTALL_PROPRIETARY)
|
||||
include(FindSCP)
|
||||
if(DEBUG_PREBUILT)
|
||||
message("cd ${SCRIPTS_DIR} && ${PYTHON_EXECUTABLE} install.py --install-dir=${CMAKE_SOURCE_DIR}/.. --scp=${SCP_EXECUTABLE} ${_binary}")
|
||||
endif(DEBUG_PREBUILT)
|
||||
execute_process(COMMAND ${PYTHON_EXECUTABLE}
|
||||
install.py
|
||||
--install-dir=${CMAKE_SOURCE_DIR}/..
|
||||
--scp=${SCP_EXECUTABLE}
|
||||
${_binary}
|
||||
WORKING_DIRECTORY ${SCRIPTS_DIR}
|
||||
RESULT_VARIABLE ${_binary}_installed
|
||||
)
|
||||
else(INSTALL_PROPRIETARY)
|
||||
if(DEBUG_PREBUILT)
|
||||
message("cd ${SCRIPTS_DIR} && ${PYTHON_EXECUTABLE} install.py --install-dir=${CMAKE_SOURCE_DIR}/.. ${_binary}")
|
||||
endif(DEBUG_PREBUILT)
|
||||
execute_process(COMMAND ${PYTHON_EXECUTABLE}
|
||||
install.py
|
||||
--install-dir=${CMAKE_SOURCE_DIR}/..
|
||||
${_binary}
|
||||
WORKING_DIRECTORY ${SCRIPTS_DIR}
|
||||
RESULT_VARIABLE ${_binary}_installed
|
||||
)
|
||||
endif(INSTALL_PROPRIETARY)
|
||||
if(DEBUG_PREBUILT)
|
||||
message("cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install
|
||||
--install-dir=${AUTOBUILD_INSTALL_DIR}
|
||||
--skip-license-check
|
||||
${_binary} ")
|
||||
endif(DEBUG_PREBUILT)
|
||||
execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}"
|
||||
install
|
||||
--install-dir=${AUTOBUILD_INSTALL_DIR}
|
||||
--skip-license-check
|
||||
${_binary}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
RESULT_VARIABLE ${_binary}_installed
|
||||
)
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/temp/${_binary}_installed "${${_binary}_installed}")
|
||||
else(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
|
||||
set(${_binary}_installed 0)
|
||||
|
|
@ -40,5 +35,5 @@ macro (use_prebuilt_binary _binary)
|
|||
"Failed to download or unpack prebuilt '${_binary}'."
|
||||
" Process returned ${${_binary}_installed}.")
|
||||
endif (NOT ${_binary}_installed EQUAL 0)
|
||||
endif (NOT STANDALONE)
|
||||
endif (NOT STANDALONE_${_binary})
|
||||
endmacro (use_prebuilt_binary _binary)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ elseif (WINDOWS)
|
|||
endif (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY)
|
||||
|
||||
include_directories(
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/quicktime
|
||||
${LIBS_PREBUILT_DIR}/include/quicktime
|
||||
"${QUICKTIME_SDK_DIR}\\CIncludes"
|
||||
)
|
||||
endif (DARWIN)
|
||||
|
|
|
|||
|
|
@ -5,11 +5,10 @@ include(Python)
|
|||
macro (check_message_template _target)
|
||||
add_custom_command(
|
||||
TARGET ${_target}
|
||||
POST_BUILD
|
||||
PRE_LINK
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
ARGS ${SCRIPTS_DIR}/md5check.py
|
||||
3f19d130400c547de36278a6b6f9b028
|
||||
${SCRIPTS_DIR}/messages/message_template.msg
|
||||
ARGS ${SCRIPTS_DIR}/template_verifier.py
|
||||
--mode=development --cache_master --master_url=${TEMPLATE_VERIFIER_MASTER_URL} ${TEMPLATE_VERIFIER_OPTIONS}
|
||||
COMMENT "Verifying message template - See http://wiki.secondlife.com/wiki/Template_verifier.py"
|
||||
)
|
||||
endmacro (check_message_template)
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ else (STANDALONE)
|
|||
endif (LINUX)
|
||||
|
||||
include_directories (
|
||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include
|
||||
${LIBS_PREBUILT_DIR}/include
|
||||
${LIBS_PREBUILT_DIR}/include
|
||||
)
|
||||
foreach(include ${${LL_ARCH}_INCLUDES})
|
||||
include_directories(${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/${include})
|
||||
include_directories(${LIBS_PREBUILT_DIR}/include/${include})
|
||||
endforeach(include)
|
||||
endif (STANDALONE)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
# Relative and absolute paths to subtrees.
|
||||
|
||||
if(NOT DEFINED COMMON_CMAKE_DIR)
|
||||
set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")
|
||||
endif(NOT DEFINED COMMON_CMAKE_DIR)
|
||||
|
||||
set(LIBS_CLOSED_PREFIX)
|
||||
set(LIBS_OPEN_PREFIX)
|
||||
set(LIBS_SERVER_PREFIX)
|
||||
|
|
@ -26,21 +30,39 @@ set(VIEWER_PREFIX)
|
|||
set(INTEGRATION_TESTS_PREFIX)
|
||||
set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
|
||||
|
||||
set(LIBS_CLOSED_DIR ${CMAKE_SOURCE_DIR}/${LIBS_CLOSED_PREFIX})
|
||||
set(LIBS_OPEN_DIR ${CMAKE_SOURCE_DIR}/${LIBS_OPEN_PREFIX})
|
||||
if(LIBS_CLOSED_DIR)
|
||||
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)
|
||||
else(LIBS_CLOSED_DIR)
|
||||
set(LIBS_CLOSED_DIR ${CMAKE_SOURCE_DIR}/${LIBS_CLOSED_PREFIX})
|
||||
endif(LIBS_CLOSED_DIR)
|
||||
if(LIBS_COMMON_DIR)
|
||||
file(TO_CMAKE_PATH "${LIBS_COMMON_DIR}" LIBS_COMMON_DIR)
|
||||
else(LIBS_COMMON_DIR)
|
||||
set(LIBS_COMMON_DIR ${CMAKE_SOURCE_DIR}/${LIBS_OPEN_PREFIX})
|
||||
endif(LIBS_COMMON_DIR)
|
||||
set(LIBS_OPEN_DIR ${LIBS_COMMON_DIR})
|
||||
|
||||
set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX})
|
||||
set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
|
||||
set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX})
|
||||
set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
|
||||
|
||||
set(LIBS_PREBUILT_DIR ${CMAKE_SOURCE_DIR}/../libraries CACHE PATH
|
||||
set(AUTOBUILD_INSTALL_DIR ${CMAKE_BINARY_DIR}/packages)
|
||||
|
||||
set(LIBS_PREBUILT_DIR ${AUTOBUILD_INSTALL_DIR} CACHE PATH
|
||||
"Location of prebuilt libraries.")
|
||||
|
||||
if (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)
|
||||
# We use this as a marker that you can try to use the proprietary libraries.
|
||||
set(INSTALL_PROPRIETARY ON CACHE BOOL "Install proprietary binaries")
|
||||
endif (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)
|
||||
set(TEMPLATE_VERIFIER_OPTIONS "" CACHE STRING "Options for scripts/template_verifier.py")
|
||||
set(TEMPLATE_VERIFIER_MASTER_URL "http://bitbucket.org/lindenlab/master-message-template/raw/tip/message_template.msg" CACHE STRING "Location of the master message template")
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
|
||||
"Build type. One of: Debug Release RelWithDebInfo" FORCE)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
set(WINDOWS ON BOOL FORCE)
|
||||
|
|
@ -54,20 +76,19 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||
set(LINUX ON BOOl FORCE)
|
||||
|
||||
# If someone has specified a word size, use that to determine the
|
||||
# architecture. Otherwise, let the compiler specify the word size.
|
||||
# Using uname will break under chroots and other cross arch compiles. RC
|
||||
# architecture. Otherwise, let the architecture specify the word size.
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
set(ARCH i686)
|
||||
elseif (WORD_SIZE EQUAL 64)
|
||||
set(ARCH x86_64)
|
||||
else (WORD_SIZE EQUAL 32)
|
||||
if(CMAKE_SIZEOF_VOID_P MATCHES 4)
|
||||
set(ARCH i686)
|
||||
set(WORD_SIZE 32)
|
||||
else(CMAKE_SIZEOF_VOID_P MATCHES 4)
|
||||
set(ARCH x86_64)
|
||||
execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/
|
||||
OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (ARCH STREQUAL x86_64)
|
||||
set(WORD_SIZE 64)
|
||||
endif(CMAKE_SIZEOF_VOID_P MATCHES 4)
|
||||
else (ARCH STREQUAL x86_64)
|
||||
set(WORD_SIZE 32)
|
||||
endif (ARCH STREQUAL x86_64)
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
|
||||
set(LL_ARCH ${ARCH}_linux)
|
||||
|
|
@ -76,25 +97,12 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(DARWIN 1)
|
||||
|
||||
# NOTE: If specifying a different SDK with CMAKE_OSX_SYSROOT at configure
|
||||
# time you should also specify CMAKE_OSX_DEPLOYMENT_TARGET explicitly,
|
||||
# otherwise CMAKE_OSX_SYSROOT will be overridden here. We can't just check
|
||||
# for it being unset, as it gets set to the system default :(
|
||||
|
||||
# Default to building against the 10.4 SDK if no deployment target is
|
||||
# specified.
|
||||
if (NOT CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
# NOTE: setting -isysroot is NOT adequate: http://lists.apple.com/archives/Xcode-users/2007/Oct/msg00696.html
|
||||
# see http://public.kitware.com/Bug/view.php?id=9959 + poppy
|
||||
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.4)
|
||||
endif (NOT CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
|
||||
# GCC 4.2 is incompatible with the MacOSX 10.4 SDK
|
||||
if (${CMAKE_OSX_SYSROOT} MATCHES "10.4u")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.0")
|
||||
endif (${CMAKE_OSX_SYSROOT} MATCHES "10.4u")
|
||||
|
||||
# To support a different SDK update these Xcode settings:
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
|
||||
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.2")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "DWARF with dSYM File")
|
||||
|
||||
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:
|
||||
# -DCMAKE_OSX_ARCHITECTURES:STRING='i386;ppc'
|
||||
|
|
@ -125,6 +133,7 @@ set(VIEWER ON CACHE BOOL "Build Second Life viewer.")
|
|||
set(VIEWER_CHANNEL "LindenDeveloper" CACHE STRING "Viewer Channel Name")
|
||||
set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing")
|
||||
|
||||
set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
|
||||
set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")
|
||||
|
||||
if (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
|
||||
|
|
@ -141,6 +150,7 @@ For more information, please see JIRA DEV-14943 - Cmake Linux cannot build both
|
|||
endif (LINUX AND SERVER AND VIEWER)
|
||||
|
||||
|
||||
set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
|
||||
set(USE_PRECOMPILED_HEADERS OFF CACHE BOOL "Enable use of precompiled header directives where supported.")
|
||||
|
||||
source_group("CMake Rules" FILES CMakeLists.txt)
|
||||
|
||||
|
|
|
|||
|
|
@ -62,16 +62,13 @@ elseif (LINUX)
|
|||
else (STANDALONE)
|
||||
set(WEBKIT_PLUGIN_LIBRARIES
|
||||
llqtwebkit
|
||||
|
||||
qgif
|
||||
qjpeg
|
||||
|
||||
QtWebKit
|
||||
QtOpenGL
|
||||
QtNetwork
|
||||
QtGui
|
||||
QtCore
|
||||
|
||||
qgif
|
||||
qjpeg
|
||||
jpeg
|
||||
fontconfig
|
||||
X11
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ if (STANDALONE)
|
|||
else (STANDALONE)
|
||||
use_prebuilt_binary(xmlrpc-epi)
|
||||
if (WINDOWS)
|
||||
set(XMLRPCEPI_LIBRARIES xmlrpcepi)
|
||||
set(XMLRPCEPI_LIBRARIES
|
||||
debug xmlrpc-epid
|
||||
optimized xmlrpc-epi
|
||||
)
|
||||
else (WINDOWS)
|
||||
set(XMLRPCEPI_LIBRARIES xmlrpc-epi)
|
||||
endif (WINDOWS)
|
||||
|
|
|
|||
863
indra/develop.py
863
indra/develop.py
|
|
@ -1,863 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""\
|
||||
@file develop.py
|
||||
@authors Bryan O'Sullivan, Mark Palange, Aaron Brashears
|
||||
@brief Fire and forget script to appropriately configure cmake for SL.
|
||||
|
||||
$LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
Second Life Viewer Source Code
|
||||
Copyright (C) 2007-2011, Linden Research, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation;
|
||||
version 2.1 of the License only.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
$/LicenseInfo$
|
||||
"""
|
||||
|
||||
|
||||
import errno
|
||||
import getopt
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import shutil
|
||||
import socket
|
||||
import sys
|
||||
import commands
|
||||
import subprocess
|
||||
|
||||
class CommandError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def mkdir(path):
|
||||
try:
|
||||
os.mkdir(path)
|
||||
return path
|
||||
except OSError, err:
|
||||
if err.errno != errno.EEXIST or not os.path.isdir(path):
|
||||
raise
|
||||
|
||||
def getcwd():
|
||||
cwd = os.getcwd()
|
||||
if 'a' <= cwd[0] <= 'z' and cwd[1] == ':':
|
||||
# CMake wants DOS drive letters to be in uppercase. The above
|
||||
# condition never asserts on platforms whose full path names
|
||||
# always begin with a slash, so we don't need to test whether
|
||||
# we are running on Windows.
|
||||
cwd = cwd[0].upper() + cwd[1:]
|
||||
return cwd
|
||||
|
||||
def quote(opts):
|
||||
return '"' + '" "'.join([ opt.replace('"', '') for opt in opts ]) + '"'
|
||||
|
||||
class PlatformSetup(object):
|
||||
generator = None
|
||||
build_types = {}
|
||||
for t in ('Debug', 'Release', 'RelWithDebInfo'):
|
||||
build_types[t.lower()] = t
|
||||
|
||||
build_type = build_types['relwithdebinfo']
|
||||
standalone = 'OFF'
|
||||
unattended = 'OFF'
|
||||
universal = 'OFF'
|
||||
project_name = 'SecondLife'
|
||||
distcc = True
|
||||
cmake_opts = []
|
||||
word_size = 32
|
||||
using_express = False
|
||||
|
||||
def __init__(self):
|
||||
self.script_dir = os.path.realpath(
|
||||
os.path.dirname(__import__(__name__).__file__))
|
||||
|
||||
def os(self):
|
||||
'''Return the name of the OS.'''
|
||||
|
||||
raise NotImplemented('os')
|
||||
|
||||
def arch(self):
|
||||
'''Return the CPU architecture.'''
|
||||
|
||||
return None
|
||||
|
||||
def platform(self):
|
||||
'''Return a stringified two-tuple of the OS name and CPU
|
||||
architecture.'''
|
||||
|
||||
ret = self.os()
|
||||
if self.arch():
|
||||
ret += '-' + self.arch()
|
||||
return ret
|
||||
|
||||
def build_dirs(self):
|
||||
'''Return the top-level directories in which builds occur.
|
||||
|
||||
This can return more than one directory, e.g. if doing a
|
||||
32-bit viewer and server build on Linux.'''
|
||||
|
||||
return ['build-' + self.platform()]
|
||||
|
||||
def cmake_commandline(self, src_dir, build_dir, opts, simple):
|
||||
'''Return the command line to run cmake with.'''
|
||||
|
||||
args = dict(
|
||||
dir=src_dir,
|
||||
generator=self.generator,
|
||||
opts=quote(opts),
|
||||
standalone=self.standalone,
|
||||
unattended=self.unattended,
|
||||
word_size=self.word_size,
|
||||
type=self.build_type.upper(),
|
||||
)
|
||||
#if simple:
|
||||
# return 'cmake %(opts)s %(dir)r' % args
|
||||
return ('cmake -DCMAKE_BUILD_TYPE:STRING=%(type)s '
|
||||
'-DSTANDALONE:BOOL=%(standalone)s '
|
||||
'-DUNATTENDED:BOOL=%(unattended)s '
|
||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||
'-G %(generator)r %(opts)s %(dir)r' % args)
|
||||
|
||||
def run_cmake(self, args=[]):
|
||||
'''Run cmake.'''
|
||||
|
||||
# do a sanity check to make sure we have a generator
|
||||
if not hasattr(self, 'generator'):
|
||||
raise "No generator available for '%s'" % (self.__name__,)
|
||||
cwd = getcwd()
|
||||
created = []
|
||||
try:
|
||||
for d in self.build_dirs():
|
||||
simple = True
|
||||
if mkdir(d):
|
||||
created.append(d)
|
||||
simple = False
|
||||
try:
|
||||
os.chdir(d)
|
||||
cmd = self.cmake_commandline(cwd, d, args, simple)
|
||||
print 'Running %r in %r' % (cmd, d)
|
||||
self.run(cmd, 'cmake')
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
except:
|
||||
# If we created a directory in which to run cmake and
|
||||
# something went wrong, the directory probably just
|
||||
# contains garbage, so delete it.
|
||||
os.chdir(cwd)
|
||||
for d in created:
|
||||
print 'Cleaning %r' % d
|
||||
shutil.rmtree(d)
|
||||
raise
|
||||
|
||||
def parse_build_opts(self, arguments):
|
||||
opts, targets = getopt.getopt(arguments, 'o:', ['option='])
|
||||
build_opts = []
|
||||
for o, a in opts:
|
||||
if o in ('-o', '--option'):
|
||||
build_opts.append(a)
|
||||
return build_opts, targets
|
||||
|
||||
def run_build(self, opts, targets):
|
||||
'''Build the default targets for this platform.'''
|
||||
|
||||
raise NotImplemented('run_build')
|
||||
|
||||
def cleanup(self):
|
||||
'''Delete all build directories.'''
|
||||
|
||||
cleaned = 0
|
||||
for d in self.build_dirs():
|
||||
if os.path.isdir(d):
|
||||
print 'Cleaning %r' % d
|
||||
shutil.rmtree(d)
|
||||
cleaned += 1
|
||||
if not cleaned:
|
||||
print 'Nothing to clean up!'
|
||||
|
||||
def is_internal_tree(self):
|
||||
'''Indicate whether we are building in an internal source tree.'''
|
||||
|
||||
return os.path.isdir(os.path.join(self.script_dir, 'newsim'))
|
||||
|
||||
def find_in_path(self, name, defval=None, basename=False):
|
||||
for ext in self.exe_suffixes:
|
||||
name_ext = name + ext
|
||||
if os.sep in name_ext:
|
||||
path = os.path.abspath(name_ext)
|
||||
if os.access(path, os.X_OK):
|
||||
return [basename and os.path.basename(path) or path]
|
||||
for p in os.getenv('PATH', self.search_path).split(os.pathsep):
|
||||
path = os.path.join(p, name_ext)
|
||||
if os.access(path, os.X_OK):
|
||||
return [basename and os.path.basename(path) or path]
|
||||
if defval:
|
||||
return [defval]
|
||||
return []
|
||||
|
||||
|
||||
class UnixSetup(PlatformSetup):
|
||||
'''Generic Unixy build instructions.'''
|
||||
|
||||
search_path = '/usr/bin:/usr/local/bin'
|
||||
exe_suffixes = ('',)
|
||||
|
||||
def __init__(self):
|
||||
super(UnixSetup, self).__init__()
|
||||
self.generator = 'Unix Makefiles'
|
||||
|
||||
def os(self):
|
||||
return 'unix'
|
||||
|
||||
def arch(self):
|
||||
cpu = os.uname()[-1]
|
||||
if cpu.endswith('386'):
|
||||
cpu = 'i386'
|
||||
elif cpu.endswith('86'):
|
||||
cpu = 'i686'
|
||||
elif cpu in ('athlon',):
|
||||
cpu = 'i686'
|
||||
elif cpu == 'Power Macintosh':
|
||||
cpu = 'ppc'
|
||||
elif cpu == 'x86_64' and self.word_size == 32:
|
||||
cpu = 'i686'
|
||||
return cpu
|
||||
|
||||
def run(self, command, name=None):
|
||||
'''Run a program. If the program fails, raise an exception.'''
|
||||
sys.stdout.flush()
|
||||
ret = os.system(command)
|
||||
if ret:
|
||||
if name is None:
|
||||
name = command.split(None, 1)[0]
|
||||
if os.WIFEXITED(ret):
|
||||
st = os.WEXITSTATUS(ret)
|
||||
if st == 127:
|
||||
event = 'was not found'
|
||||
else:
|
||||
event = 'exited with status %d' % st
|
||||
elif os.WIFSIGNALED(ret):
|
||||
event = 'was killed by signal %d' % os.WTERMSIG(ret)
|
||||
else:
|
||||
event = 'died unexpectedly (!?) with 16-bit status %d' % ret
|
||||
raise CommandError('the command %r %s' %
|
||||
(name, event))
|
||||
|
||||
|
||||
class LinuxSetup(UnixSetup):
|
||||
def __init__(self):
|
||||
super(LinuxSetup, self).__init__()
|
||||
try:
|
||||
self.debian_sarge = open('/etc/debian_version').read().strip() == '3.1'
|
||||
except:
|
||||
self.debian_sarge = False
|
||||
|
||||
def os(self):
|
||||
return 'linux'
|
||||
|
||||
def build_dirs(self):
|
||||
# Only build the server code if we have it.
|
||||
platform_build = '%s-%s' % (self.platform(), self.build_type.lower())
|
||||
|
||||
if self.arch() == 'i686' and self.is_internal_tree():
|
||||
return ['viewer-' + platform_build, 'server-' + platform_build]
|
||||
elif self.arch() == 'x86_64' and self.is_internal_tree():
|
||||
# the viewer does not build in 64bit -- kdu5 issues
|
||||
# we can either use openjpeg, or overhaul our viewer to handle kdu5 or higher
|
||||
# doug knows about kdu issues
|
||||
return ['server-' + platform_build]
|
||||
else:
|
||||
return ['viewer-' + platform_build]
|
||||
|
||||
def cmake_commandline(self, src_dir, build_dir, opts, simple):
|
||||
args = dict(
|
||||
dir=src_dir,
|
||||
generator=self.generator,
|
||||
opts=quote(opts),
|
||||
standalone=self.standalone,
|
||||
unattended=self.unattended,
|
||||
type=self.build_type.upper(),
|
||||
project_name=self.project_name,
|
||||
word_size=self.word_size,
|
||||
)
|
||||
if not self.is_internal_tree():
|
||||
args.update({'cxx':'g++', 'server':'OFF', 'viewer':'ON'})
|
||||
else:
|
||||
if self.distcc:
|
||||
distcc = self.find_in_path('distcc')
|
||||
baseonly = True
|
||||
else:
|
||||
distcc = []
|
||||
baseonly = False
|
||||
if 'server' in build_dir:
|
||||
gcc = distcc + self.find_in_path(
|
||||
self.debian_sarge and 'g++-3.3' or 'g++-4.1',
|
||||
'g++', baseonly)
|
||||
args.update({'cxx': ' '.join(gcc), 'server': 'ON',
|
||||
'viewer': 'OFF'})
|
||||
else:
|
||||
gcc41 = distcc + self.find_in_path('g++-4.1', 'g++', baseonly)
|
||||
args.update({'cxx': ' '.join(gcc41),
|
||||
'server': 'OFF',
|
||||
'viewer': 'ON'})
|
||||
cmd = (('cmake -DCMAKE_BUILD_TYPE:STRING=%(type)s '
|
||||
'-G %(generator)r -DSERVER:BOOL=%(server)s '
|
||||
'-DVIEWER:BOOL=%(viewer)s -DSTANDALONE:BOOL=%(standalone)s '
|
||||
'-DUNATTENDED:BOOL=%(unattended)s '
|
||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
||||
'%(opts)s %(dir)r')
|
||||
% args)
|
||||
if 'CXX' not in os.environ:
|
||||
args.update({'cmd':cmd})
|
||||
cmd = ('CXX=%(cxx)r %(cmd)s' % args)
|
||||
return cmd
|
||||
|
||||
def run_build(self, opts, targets):
|
||||
job_count = None
|
||||
|
||||
for i in range(len(opts)):
|
||||
if opts[i].startswith('-j'):
|
||||
try:
|
||||
job_count = int(opts[i][2:])
|
||||
except ValueError:
|
||||
try:
|
||||
job_count = int(opts[i+1])
|
||||
except ValueError:
|
||||
job_count = True
|
||||
|
||||
def get_cpu_count():
|
||||
count = 0
|
||||
for line in open('/proc/cpuinfo'):
|
||||
if re.match(r'processor\s*:', line):
|
||||
count += 1
|
||||
return count
|
||||
|
||||
def localhost():
|
||||
count = get_cpu_count()
|
||||
return 'localhost/' + str(count), count
|
||||
|
||||
def get_distcc_hosts():
|
||||
try:
|
||||
hosts = []
|
||||
name = os.getenv('DISTCC_DIR', '/etc/distcc') + '/hosts'
|
||||
for l in open(name):
|
||||
l = l[l.find('#')+1:].strip()
|
||||
if l: hosts.append(l)
|
||||
return hosts
|
||||
except IOError:
|
||||
return (os.getenv('DISTCC_HOSTS', '').split() or
|
||||
[localhost()[0]])
|
||||
|
||||
def count_distcc_hosts():
|
||||
cpus = 0
|
||||
hosts = 0
|
||||
for host in get_distcc_hosts():
|
||||
m = re.match(r'.*/(\d+)', host)
|
||||
hosts += 1
|
||||
cpus += m and int(m.group(1)) or 1
|
||||
return hosts, cpus
|
||||
|
||||
def mk_distcc_hosts(basename, range, num_cpus):
|
||||
'''Generate a list of LL-internal machines to build on.'''
|
||||
loc_entry, cpus = localhost()
|
||||
hosts = [loc_entry]
|
||||
dead = []
|
||||
stations = [s for s in xrange(range) if s not in dead]
|
||||
random.shuffle(stations)
|
||||
hosts += ['%s%d.lindenlab.com/%d,lzo' % (basename, s, num_cpus) for s in stations]
|
||||
cpus += 2 * len(stations)
|
||||
return ' '.join(hosts), cpus
|
||||
|
||||
if job_count is None:
|
||||
hosts, job_count = count_distcc_hosts()
|
||||
hostname = socket.gethostname()
|
||||
if hosts == 1:
|
||||
if hostname.startswith('station'):
|
||||
hosts, job_count = mk_distcc_hosts('station', 36, 2)
|
||||
os.environ['DISTCC_HOSTS'] = hosts
|
||||
if hostname.startswith('eniac'):
|
||||
hosts, job_count = mk_distcc_hosts('eniac', 71, 2)
|
||||
os.environ['DISTCC_HOSTS'] = hosts
|
||||
if hostname.startswith('build'):
|
||||
max_jobs = 6
|
||||
else:
|
||||
max_jobs = 12
|
||||
if job_count > max_jobs:
|
||||
job_count = max_jobs;
|
||||
opts.extend(['-j', str(job_count)])
|
||||
|
||||
if targets:
|
||||
targets = ' '.join(targets)
|
||||
else:
|
||||
targets = 'all'
|
||||
|
||||
for d in self.build_dirs():
|
||||
cmd = 'make -C %r %s %s' % (d, ' '.join(opts), targets)
|
||||
print 'Running %r' % cmd
|
||||
self.run(cmd)
|
||||
|
||||
|
||||
class DarwinSetup(UnixSetup):
|
||||
def __init__(self):
|
||||
super(DarwinSetup, self).__init__()
|
||||
self.generator = 'Xcode'
|
||||
|
||||
def os(self):
|
||||
return 'darwin'
|
||||
|
||||
def arch(self):
|
||||
if self.universal == 'ON':
|
||||
return 'universal'
|
||||
else:
|
||||
return UnixSetup.arch(self)
|
||||
|
||||
def cmake_commandline(self, src_dir, build_dir, opts, simple):
|
||||
args = dict(
|
||||
dir=src_dir,
|
||||
generator=self.generator,
|
||||
opts=quote(opts),
|
||||
standalone=self.standalone,
|
||||
word_size=self.word_size,
|
||||
unattended=self.unattended,
|
||||
project_name=self.project_name,
|
||||
universal=self.universal,
|
||||
type=self.build_type.upper(),
|
||||
)
|
||||
if self.universal == 'ON':
|
||||
args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386;ppc\''
|
||||
#if simple:
|
||||
# return 'cmake %(opts)s %(dir)r' % args
|
||||
return ('cmake -G %(generator)r '
|
||||
'-DCMAKE_BUILD_TYPE:STRING=%(type)s '
|
||||
'-DSTANDALONE:BOOL=%(standalone)s '
|
||||
'-DUNATTENDED:BOOL=%(unattended)s '
|
||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
||||
'%(universal)s '
|
||||
'%(opts)s %(dir)r' % args)
|
||||
|
||||
def run_build(self, opts, targets):
|
||||
cwd = getcwd()
|
||||
if targets:
|
||||
targets = ' '.join(['-target ' + repr(t) for t in targets])
|
||||
else:
|
||||
targets = ''
|
||||
cmd = ('xcodebuild -configuration %s %s %s | grep -v "^[[:space:]]*setenv" ; exit ${PIPESTATUS[0]}' %
|
||||
(self.build_type, ' '.join(opts), targets))
|
||||
for d in self.build_dirs():
|
||||
try:
|
||||
os.chdir(d)
|
||||
print 'Running %r in %r' % (cmd, d)
|
||||
self.run(cmd)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
class WindowsSetup(PlatformSetup):
|
||||
gens = {
|
||||
'vc71' : {
|
||||
'gen' : r'Visual Studio 7 .NET 2003',
|
||||
'ver' : r'7.1'
|
||||
},
|
||||
'vc80' : {
|
||||
'gen' : r'Visual Studio 8 2005',
|
||||
'ver' : r'8.0'
|
||||
},
|
||||
'vc90' : {
|
||||
'gen' : r'Visual Studio 9 2008',
|
||||
'ver' : r'9.0'
|
||||
}
|
||||
}
|
||||
gens['vs2003'] = gens['vc71']
|
||||
gens['vs2005'] = gens['vc80']
|
||||
gens['vs2008'] = gens['vc90']
|
||||
|
||||
search_path = r'C:\windows'
|
||||
exe_suffixes = ('.exe', '.bat', '.com')
|
||||
|
||||
def __init__(self):
|
||||
super(WindowsSetup, self).__init__()
|
||||
self._generator = None
|
||||
self.incredibuild = False
|
||||
|
||||
def _get_generator(self):
|
||||
if self._generator is None:
|
||||
for version in 'vc80 vc90 vc71'.split():
|
||||
if self.find_visual_studio(version):
|
||||
self._generator = version
|
||||
print 'Building with ', self.gens[version]['gen']
|
||||
break
|
||||
else:
|
||||
print >> sys.stderr, 'Cannot find a Visual Studio installation, testing for express editions'
|
||||
for version in 'vc80 vc90 vc71'.split():
|
||||
if self.find_visual_studio_express(version):
|
||||
self._generator = version
|
||||
self.using_express = True
|
||||
print 'Building with ', self.gens[version]['gen'] , "Express edition"
|
||||
break
|
||||
else:
|
||||
print >> sys.stderr, 'Cannot find any Visual Studio installation'
|
||||
sys.exit(1)
|
||||
return self._generator
|
||||
|
||||
def _set_generator(self, gen):
|
||||
self._generator = gen
|
||||
|
||||
generator = property(_get_generator, _set_generator)
|
||||
|
||||
def os(self):
|
||||
return 'win32'
|
||||
|
||||
def build_dirs(self):
|
||||
return ['build-' + self.generator]
|
||||
|
||||
def cmake_commandline(self, src_dir, build_dir, opts, simple):
|
||||
args = dict(
|
||||
dir=src_dir,
|
||||
generator=self.gens[self.generator.lower()]['gen'],
|
||||
opts=quote(opts),
|
||||
standalone=self.standalone,
|
||||
unattended=self.unattended,
|
||||
project_name=self.project_name,
|
||||
word_size=self.word_size,
|
||||
)
|
||||
#if simple:
|
||||
# return 'cmake %(opts)s "%(dir)s"' % args
|
||||
return ('cmake -G "%(generator)s" '
|
||||
'-DSTANDALONE:BOOL=%(standalone)s '
|
||||
'-DUNATTENDED:BOOL=%(unattended)s '
|
||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
||||
'%(opts)s "%(dir)s"' % args)
|
||||
|
||||
def get_HKLM_registry_value(self, key_str, value_str):
|
||||
import _winreg
|
||||
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
|
||||
key = _winreg.OpenKey(reg, key_str)
|
||||
value = _winreg.QueryValueEx(key, value_str)[0]
|
||||
print 'Found: %s' % value
|
||||
return value
|
||||
|
||||
def find_visual_studio(self, gen=None):
|
||||
if gen is None:
|
||||
gen = self._generator
|
||||
gen = gen.lower()
|
||||
value_str = (r'EnvironmentDirectory')
|
||||
key_str = (r'SOFTWARE\Microsoft\VisualStudio\%s\Setup\VS' %
|
||||
self.gens[gen]['ver'])
|
||||
print ('Reading VS environment from HKEY_LOCAL_MACHINE\%s\%s' %
|
||||
(key_str, value_str))
|
||||
try:
|
||||
return self.get_HKLM_registry_value(key_str, value_str)
|
||||
except WindowsError, err:
|
||||
key_str = (r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%s\Setup\VS' %
|
||||
self.gens[gen]['ver'])
|
||||
|
||||
try:
|
||||
return self.get_HKLM_registry_value(key_str, value_str)
|
||||
except:
|
||||
print >> sys.stderr, "Didn't find ", self.gens[gen]['gen']
|
||||
|
||||
return ''
|
||||
|
||||
def find_visual_studio_express(self, gen=None):
|
||||
if gen is None:
|
||||
gen = self._generator
|
||||
gen = gen.lower()
|
||||
try:
|
||||
import _winreg
|
||||
key_str = (r'SOFTWARE\Microsoft\VCEXpress\%s\Setup\VC' %
|
||||
self.gens[gen]['ver'])
|
||||
value_str = (r'ProductDir')
|
||||
print ('Reading VS environment from HKEY_LOCAL_MACHINE\%s\%s' %
|
||||
(key_str, value_str))
|
||||
print key_str
|
||||
|
||||
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
|
||||
key = _winreg.OpenKey(reg, key_str)
|
||||
value = _winreg.QueryValueEx(key, value_str)[0]+"IDE"
|
||||
print 'Found: %s' % value
|
||||
return value
|
||||
except WindowsError, err:
|
||||
print >> sys.stderr, "Didn't find ", self.gens[gen]['gen']
|
||||
return ''
|
||||
|
||||
def get_build_cmd(self):
|
||||
if self.incredibuild:
|
||||
config = self.build_type
|
||||
if self.gens[self.generator]['ver'] in [ r'8.0', r'9.0' ]:
|
||||
config = '\"%s|Win32\"' % config
|
||||
|
||||
executable = 'buildconsole'
|
||||
cmd = "%(bin)s %(prj)s.sln /build /cfg=%(cfg)s" % {'prj': self.project_name, 'cfg': config, 'bin': executable}
|
||||
return (executable, cmd)
|
||||
|
||||
environment = self.find_visual_studio()
|
||||
if environment == '':
|
||||
environment = self.find_visual_studio_express()
|
||||
if environment == '':
|
||||
print >> sys.stderr, "Something went very wrong during build stage, could not find a Visual Studio installation."
|
||||
else:
|
||||
build_dirs=self.build_dirs();
|
||||
print >> sys.stderr, "\nSolution generation complete, it can can now be found in:", build_dirs[0]
|
||||
print >> sys.stderr, "\nPlease see https://wiki.secondlife.com/wiki/Microsoft_Visual_Studio#Extra_steps_for_Visual_Studio_Express_editions for express specific information"
|
||||
exit(0)
|
||||
|
||||
# devenv.com is CLI friendly, devenv.exe... not so much.
|
||||
executable = '%sdevenv.com' % (self.find_visual_studio(),)
|
||||
cmd = ('"%s" %s.sln /build %s' %
|
||||
(executable, self.project_name, self.build_type))
|
||||
return (executable, cmd)
|
||||
|
||||
def run(self, command, name=None, retry_on=None, retries=1):
|
||||
'''Run a program. If the program fails, raise an exception.'''
|
||||
assert name is not None, 'On windows an executable path must be given in name. [DEV-44838]'
|
||||
if os.path.isfile(name):
|
||||
path = name
|
||||
else:
|
||||
path = self.find_in_path(name)[0]
|
||||
while retries:
|
||||
retries = retries - 1
|
||||
print "develop.py tries to run:", command
|
||||
ret = subprocess.call(command, executable=path)
|
||||
print "got ret", ret, "from", command
|
||||
if ret == 0:
|
||||
break
|
||||
else:
|
||||
error = 'exited with status %d' % ret
|
||||
if retry_on is not None and retry_on == ret:
|
||||
print "Retrying... the command %r %s" % (name, error)
|
||||
else:
|
||||
raise CommandError('the command %r %s' % (name, error))
|
||||
|
||||
def run_cmake(self, args=[]):
|
||||
'''Override to add the vstool.exe call after running cmake.'''
|
||||
PlatformSetup.run_cmake(self, args)
|
||||
if self.unattended == 'OFF':
|
||||
if self.using_express == False:
|
||||
self.run_vstool()
|
||||
|
||||
def run_vstool(self):
|
||||
for build_dir in self.build_dirs():
|
||||
stamp = os.path.join(build_dir, 'vstool.txt')
|
||||
try:
|
||||
prev_build = open(stamp).read().strip()
|
||||
except IOError:
|
||||
prev_build = ''
|
||||
if prev_build == self.build_type:
|
||||
# Only run vstool if the build type has changed.
|
||||
continue
|
||||
executable = os.path.join('tools','vstool','VSTool.exe')
|
||||
vstool_cmd = (executable +
|
||||
' --solution ' +
|
||||
os.path.join(build_dir,'SecondLife.sln') +
|
||||
' --config ' + self.build_type +
|
||||
' --startup secondlife-bin')
|
||||
print 'Running %r in %r' % (vstool_cmd, getcwd())
|
||||
self.run(vstool_cmd, name=executable)
|
||||
print >> open(stamp, 'w'), self.build_type
|
||||
|
||||
def run_build(self, opts, targets):
|
||||
for t in targets:
|
||||
assert t.strip(), 'Unexpected empty targets: ' + repr(targets)
|
||||
cwd = getcwd()
|
||||
executable, build_cmd = self.get_build_cmd()
|
||||
|
||||
for d in self.build_dirs():
|
||||
try:
|
||||
os.chdir(d)
|
||||
if targets:
|
||||
for t in targets:
|
||||
cmd = '%s /project %s %s' % (build_cmd, t, ' '.join(opts))
|
||||
print 'Running %r in %r' % (cmd, d)
|
||||
self.run(cmd, name=executable, retry_on=4, retries=3)
|
||||
else:
|
||||
cmd = '%s %s' % (build_cmd, ' '.join(opts))
|
||||
print 'Running %r in %r' % (cmd, d)
|
||||
self.run(cmd, name=executable, retry_on=4, retries=3)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
class CygwinSetup(WindowsSetup):
|
||||
def __init__(self):
|
||||
super(CygwinSetup, self).__init__()
|
||||
self.generator = 'vc80'
|
||||
|
||||
def cmake_commandline(self, src_dir, build_dir, opts, simple):
|
||||
dos_dir = commands.getoutput("cygpath -w %s" % src_dir)
|
||||
args = dict(
|
||||
dir=dos_dir,
|
||||
generator=self.gens[self.generator.lower()]['gen'],
|
||||
opts=quote(opts),
|
||||
standalone=self.standalone,
|
||||
unattended=self.unattended,
|
||||
project_name=self.project_name,
|
||||
word_size=self.word_size,
|
||||
)
|
||||
#if simple:
|
||||
# return 'cmake %(opts)s "%(dir)s"' % args
|
||||
return ('cmake -G "%(generator)s" '
|
||||
'-DUNATTENDED:BOOl=%(unattended)s '
|
||||
'-DSTANDALONE:BOOL=%(standalone)s '
|
||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
||||
'%(opts)s "%(dir)s"' % args)
|
||||
|
||||
setup_platform = {
|
||||
'darwin': DarwinSetup,
|
||||
'linux2': LinuxSetup,
|
||||
'win32' : WindowsSetup,
|
||||
'cygwin' : CygwinSetup
|
||||
}
|
||||
|
||||
|
||||
usage_msg = '''
|
||||
Usage: develop.py [options] [command [command-options]]
|
||||
|
||||
Options:
|
||||
-h | --help print this help message
|
||||
--standalone build standalone, without Linden prebuild libraries
|
||||
--unattended build unattended, do not invoke any tools requiring
|
||||
a human response
|
||||
--universal build a universal binary on Mac OS X (unsupported)
|
||||
-t | --type=NAME build type ("Debug", "Release", or "RelWithDebInfo")
|
||||
-m32 | -m64 build architecture (32-bit or 64-bit)
|
||||
-N | --no-distcc disable use of distcc
|
||||
-G | --generator=NAME generator name
|
||||
Windows: VC71 or VS2003 (default), VC80 (VS2005) or
|
||||
VC90 (VS2008)
|
||||
Mac OS X: Xcode (default), Unix Makefiles
|
||||
Linux: Unix Makefiles (default), KDevelop3
|
||||
-p | --project=NAME set the root project name. (Doesn't effect makefiles)
|
||||
|
||||
Commands:
|
||||
build configure and build default target
|
||||
clean delete all build directories, does not affect sources
|
||||
configure configure project by running cmake (default if none given)
|
||||
printbuilddirs print the build directory that will be used
|
||||
|
||||
Command-options for "configure":
|
||||
We use cmake variables to change the build configuration.
|
||||
-DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc
|
||||
-DVIEWER:BOOL=OFF Don't configure the viewer
|
||||
-DPACKAGE:BOOL=ON Create "package" target to make installers
|
||||
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
|
||||
|
||||
Examples:
|
||||
Set up a viewer-only project for your system:
|
||||
develop.py configure -DSERVER:BOOL=OFF
|
||||
|
||||
Set up a Visual Studio 2005 project with "package" target:
|
||||
develop.py -G vc80 configure -DPACKAGE:BOOL=ON
|
||||
'''
|
||||
|
||||
def main(arguments):
|
||||
setup = setup_platform[sys.platform]()
|
||||
try:
|
||||
opts, args = getopt.getopt(
|
||||
arguments,
|
||||
'?hNt:p:G:m:',
|
||||
['help', 'standalone', 'no-distcc', 'unattended', 'universal', 'type=', 'incredibuild', 'generator=', 'project='])
|
||||
except getopt.GetoptError, err:
|
||||
print >> sys.stderr, 'Error:', err
|
||||
print >> sys.stderr, """
|
||||
Note: You must pass -D options to cmake after the "configure" command
|
||||
For example: develop.py configure -DSERVER:BOOL=OFF"""
|
||||
print >> sys.stderr, usage_msg.strip()
|
||||
sys.exit(1)
|
||||
|
||||
for o, a in opts:
|
||||
if o in ('-?', '-h', '--help'):
|
||||
print usage_msg.strip()
|
||||
sys.exit(0)
|
||||
elif o in ('--standalone',):
|
||||
setup.standalone = 'ON'
|
||||
elif o in ('--unattended',):
|
||||
setup.unattended = 'ON'
|
||||
elif o in ('--universal',):
|
||||
setup.universal = 'ON'
|
||||
elif o in ('-m',):
|
||||
if a in ('32', '64'):
|
||||
setup.word_size = int(a)
|
||||
else:
|
||||
print >> sys.stderr, 'Error: unknown word size', repr(a)
|
||||
print >> sys.stderr, 'Supported word sizes: 32, 64'
|
||||
sys.exit(1)
|
||||
elif o in ('-t', '--type'):
|
||||
try:
|
||||
setup.build_type = setup.build_types[a.lower()]
|
||||
except KeyError:
|
||||
print >> sys.stderr, 'Error: unknown build type', repr(a)
|
||||
print >> sys.stderr, 'Supported build types:'
|
||||
types = setup.build_types.values()
|
||||
types.sort()
|
||||
for t in types:
|
||||
print ' ', t
|
||||
sys.exit(1)
|
||||
elif o in ('-G', '--generator'):
|
||||
setup.generator = a
|
||||
elif o in ('-N', '--no-distcc'):
|
||||
setup.distcc = False
|
||||
elif o in ('-p', '--project'):
|
||||
setup.project_name = a
|
||||
elif o in ('--incredibuild'):
|
||||
setup.incredibuild = True
|
||||
else:
|
||||
print >> sys.stderr, 'INTERNAL ERROR: unhandled option', repr(o)
|
||||
sys.exit(1)
|
||||
if not args:
|
||||
setup.run_cmake()
|
||||
return
|
||||
try:
|
||||
cmd = args.pop(0)
|
||||
if cmd in ('cmake', 'configure'):
|
||||
setup.run_cmake(args)
|
||||
elif cmd == 'build':
|
||||
if os.getenv('DISTCC_DIR') is None:
|
||||
distcc_dir = os.path.join(getcwd(), '.distcc')
|
||||
if not os.path.exists(distcc_dir):
|
||||
os.mkdir(distcc_dir)
|
||||
print "setting DISTCC_DIR to %s" % distcc_dir
|
||||
os.environ['DISTCC_DIR'] = distcc_dir
|
||||
else:
|
||||
print "DISTCC_DIR is set to %s" % os.getenv('DISTCC_DIR')
|
||||
for d in setup.build_dirs():
|
||||
if not os.path.exists(d):
|
||||
raise CommandError('run "develop.py cmake" first')
|
||||
setup.run_cmake()
|
||||
opts, targets = setup.parse_build_opts(args)
|
||||
setup.run_build(opts, targets)
|
||||
elif cmd == 'clean':
|
||||
if args:
|
||||
raise CommandError('clean takes no arguments')
|
||||
setup.cleanup()
|
||||
elif cmd == 'printbuilddirs':
|
||||
for d in setup.build_dirs():
|
||||
print >> sys.stdout, d
|
||||
else:
|
||||
print >> sys.stderr, 'Error: unknown subcommand', repr(cmd)
|
||||
print >> sys.stderr, "(run 'develop.py --help' for help)"
|
||||
sys.exit(1)
|
||||
except getopt.GetoptError, err:
|
||||
print >> sys.stderr, 'Error with %r subcommand: %s' % (cmd, err)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main(sys.argv[1:])
|
||||
except CommandError, err:
|
||||
print >> sys.stderr, 'Error:', err
|
||||
sys.exit(1)
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
add_subdirectory(llui_libtest)
|
||||
IF (LLIMAGE_LIBTEST)
|
||||
MESSAGE(STATUS "Build llimage_libtest")
|
||||
add_subdirectory(llimage_libtest)
|
||||
ELSE (LLIMAGE_LIBTEST)
|
||||
MESSAGE(STATUS "Skip llimage_libtest")
|
||||
ENDIF (LLIMAGE_LIBTEST)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
# Integration tests of the llimage library (JPEG2000, PNG, jpeg, etc... images reading and writing)
|
||||
|
||||
project (llimage_libtest)
|
||||
|
||||
include(00-Common)
|
||||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLImageJ2COJ)
|
||||
include(LLKDU)
|
||||
include(LLVFS)
|
||||
|
||||
include_directories(
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LLVFS_INCLUDE_DIRS}
|
||||
${LLIMAGE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(llimage_libtest_SOURCE_FILES
|
||||
llimage_libtest.cpp
|
||||
)
|
||||
|
||||
set(llimage_libtest_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
llimage_libtest.h
|
||||
)
|
||||
|
||||
set_source_files_properties(${llimage_libtest_HEADER_FILES}
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
list(APPEND llimage_libtest_SOURCE_FILES ${llimage_libtest_HEADER_FILES})
|
||||
|
||||
add_executable(llimage_libtest
|
||||
WIN32
|
||||
MACOSX_BUNDLE
|
||||
${llimage_libtest_SOURCE_FILES}
|
||||
)
|
||||
|
||||
set_target_properties(llimage_libtest
|
||||
PROPERTIES
|
||||
WIN32_EXECUTABLE
|
||||
FALSE
|
||||
)
|
||||
|
||||
# OS-specific libraries
|
||||
if (DARWIN)
|
||||
include(CMakeFindFrameworks)
|
||||
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
set(OS_LIBRARIES ${COREFOUNDATION_LIBRARY})
|
||||
elseif (WINDOWS)
|
||||
set(OS_LIBRARIES)
|
||||
elseif (LINUX)
|
||||
set(OS_LIBRARIES)
|
||||
else (DARWIN)
|
||||
message(FATAL_ERROR "Unknown platform")
|
||||
endif (DARWIN)
|
||||
|
||||
# Libraries on which this application depends on
|
||||
# Sort by high-level to low-level
|
||||
target_link_libraries(llimage_libtest
|
||||
${LLCOMMON_LIBRARIES}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLIMAGE_LIBRARIES}
|
||||
${LLKDU_LIBRARIES}
|
||||
${KDU_LIBRARY}
|
||||
${LLIMAGEJ2COJ_LIBRARIES}
|
||||
${OS_LIBRARIES}
|
||||
)
|
||||
|
||||
if (DARWIN)
|
||||
# Path inside the app bundle where we'll need to copy libraries
|
||||
set(LLIMAGE_LIBTEST_DESTINATION_DIR
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llimage_libtest.app/Contents/Resources
|
||||
)
|
||||
# Create the Contents/Resources directory
|
||||
add_custom_command(
|
||||
TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS
|
||||
-E
|
||||
make_directory
|
||||
${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
COMMENT "Creating Resources directory in app bundle."
|
||||
)
|
||||
else (DARWIN)
|
||||
set(LLIMAGE_LIBTEST_DESTINATION_DIR
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
|
||||
)
|
||||
endif (DARWIN)
|
||||
|
||||
get_target_property(BUILT_LLCOMMON llcommon LOCATION)
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON} ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${BUILT_LLCOMMON}
|
||||
)
|
||||
|
||||
if (DARWIN)
|
||||
# Copy the required libraries to the package app
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib
|
||||
)
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib
|
||||
)
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib
|
||||
)
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib
|
||||
)
|
||||
endif (DARWIN)
|
||||
|
||||
if (WINDOWS)
|
||||
# Check indra/test_apps/llplugintest/CMakeLists.txt for an example of what to copy over for Windows and how
|
||||
endif (WINDOWS)
|
||||
|
||||
# Ensure people working on the viewer don't break this library
|
||||
# *NOTE: This could be removed, or only built by TeamCity, if the build
|
||||
# and link times become too long.
|
||||
add_dependencies(viewer llimage_libtest)
|
||||
|
|
@ -0,0 +1,437 @@
|
|||
/**
|
||||
* @file llimage_libtest.cpp
|
||||
* @author Merov Linden
|
||||
* @brief Integration test for the llimage library
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#include "linden_common.h"
|
||||
#include "llpointer.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
#include "llimage_libtest.h"
|
||||
|
||||
// Linden library includes
|
||||
#include "llimage.h"
|
||||
#include "llimagejpeg.h"
|
||||
#include "llimagepng.h"
|
||||
#include "llimagebmp.h"
|
||||
#include "llimagetga.h"
|
||||
#include "llimagej2c.h"
|
||||
#include "lldir.h"
|
||||
|
||||
// system libraries
|
||||
#include <iostream>
|
||||
|
||||
// doc string provided when invoking the program with --help
|
||||
static const char USAGE[] = "\n"
|
||||
"usage:\tllimage_libtest [options]\n"
|
||||
"\n"
|
||||
" -h, --help\n"
|
||||
" Print this help\n"
|
||||
" -i, --input <file1 .. file2>\n"
|
||||
" List of image files to load and convert. Patterns with wild cards can be used.\n"
|
||||
" -o, --output <file1 .. file2> OR <type>\n"
|
||||
" List of image files to create (assumes same order as for input files)\n"
|
||||
" OR 3 letters file type extension to convert each input file into.\n"
|
||||
" -log, --logmetrics <metric>\n"
|
||||
" Log performance data for <metric>. Results in <metric>.slp\n"
|
||||
" Note: so far, only ImageCompressionTester has been tested.\n"
|
||||
" -r, --analyzeperformance\n"
|
||||
" Create a report comparing <metric>_baseline.slp with current <metric>.slp\n"
|
||||
" Results in <metric>_report.csv"
|
||||
" -s, --image-stats\n"
|
||||
" Output stats for each input and output image.\n"
|
||||
"\n";
|
||||
|
||||
// true when all image loading is done. Used by metric logging thread to know when to stop the thread.
|
||||
static bool sAllDone = false;
|
||||
|
||||
// Create an empty formatted image instance of the correct type from the filename
|
||||
LLPointer<LLImageFormatted> create_image(const std::string &filename)
|
||||
{
|
||||
std::string exten = gDirUtilp->getExtension(filename);
|
||||
U32 codec = LLImageBase::getCodecFromExtension(exten);
|
||||
|
||||
LLPointer<LLImageFormatted> image;
|
||||
switch (codec)
|
||||
{
|
||||
case IMG_CODEC_BMP:
|
||||
image = new LLImageBMP();
|
||||
break;
|
||||
case IMG_CODEC_TGA:
|
||||
image = new LLImageTGA();
|
||||
break;
|
||||
case IMG_CODEC_JPEG:
|
||||
image = new LLImageJPEG();
|
||||
break;
|
||||
case IMG_CODEC_J2C:
|
||||
image = new LLImageJ2C();
|
||||
break;
|
||||
case IMG_CODEC_PNG:
|
||||
image = new LLImagePNG();
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &filename)
|
||||
{
|
||||
// Print out some statistical data on the image
|
||||
std::cout << "Image stats for : " << filename << ", extension : " << image->getExtension() << std::endl;
|
||||
|
||||
std::cout << " with : " << (int)(image->getWidth()) << ", height : " << (int)(image->getHeight()) << std::endl;
|
||||
std::cout << " comp : " << (int)(image->getComponents()) << ", levels : " << (int)(image->getDiscardLevel()) << std::endl;
|
||||
std::cout << " head : " << (int)(image->calcHeaderSize()) << ", data : " << (int)(image->getDataSize()) << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Load an image from file and return a raw (decompressed) instance of its data
|
||||
LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_stats)
|
||||
{
|
||||
LLPointer<LLImageFormatted> image = create_image(src_filename);
|
||||
|
||||
if (!image->load(src_filename))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( (image->getComponents() != 3) && (image->getComponents() != 4) )
|
||||
{
|
||||
std::cout << "Image files with less than 3 or more than 4 components are not supported\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (output_stats)
|
||||
{
|
||||
output_image_stats(image, src_filename);
|
||||
}
|
||||
|
||||
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
|
||||
if (!image->decode(raw_image, 0.0f))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return raw_image;
|
||||
}
|
||||
|
||||
// Save a raw image instance into a file
|
||||
bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, bool output_stats)
|
||||
{
|
||||
LLPointer<LLImageFormatted> image = create_image(dest_filename);
|
||||
|
||||
if (!image->encode(raw_image, 0.0f))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (output_stats)
|
||||
{
|
||||
output_image_stats(image, dest_filename);
|
||||
}
|
||||
|
||||
return image->save(dest_filename);
|
||||
}
|
||||
|
||||
void store_input_file(std::list<std::string> &input_filenames, const std::string &path)
|
||||
{
|
||||
// Break the incoming path in its components
|
||||
std::string dir = gDirUtilp->getDirName(path);
|
||||
std::string name = gDirUtilp->getBaseFileName(path);
|
||||
std::string exten = gDirUtilp->getExtension(path);
|
||||
|
||||
// std::cout << "store_input_file : " << path << ", dir : " << dir << ", name : " << name << ", exten : " << exten << std::endl;
|
||||
|
||||
// If extension is not an image type or "*", exit
|
||||
// Note: we don't support complex patterns for the extension like "j??"
|
||||
// Note: on most shells, the pattern expansion is done by the shell so that pattern matching limitation is actually not a problem
|
||||
if ((exten.compare("*") != 0) && (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((name.find('*') != -1) || ((name.find('?') != -1)))
|
||||
{
|
||||
// If file name is a pattern, iterate to get each file name and store
|
||||
std::string next_name;
|
||||
while (gDirUtilp->getNextFileInDir(dir,name,next_name))
|
||||
{
|
||||
std::string file_name = dir + gDirUtilp->getDirDelimiter() + next_name;
|
||||
input_filenames.push_back(file_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Verify that the file does exist before storing
|
||||
if (gDirUtilp->fileExists(path))
|
||||
{
|
||||
input_filenames.push_back(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "store_input_file : the file " << path << " could not be found" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void store_output_file(std::list<std::string> &output_filenames, std::list<std::string> &input_filenames, const std::string &path)
|
||||
{
|
||||
// Break the incoming path in its components
|
||||
std::string dir = gDirUtilp->getDirName(path);
|
||||
std::string name = gDirUtilp->getBaseFileName(path);
|
||||
std::string exten = gDirUtilp->getExtension(path);
|
||||
|
||||
// std::cout << "store_output_file : " << path << ", dir : " << dir << ", name : " << name << ", exten : " << exten << std::endl;
|
||||
|
||||
if (dir.empty() && exten.empty())
|
||||
{
|
||||
// If dir and exten are empty, we interpret the name as a file extension type name and will iterate through input list to populate the output list
|
||||
exten = name;
|
||||
// Make sure the extension is an image type
|
||||
if (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string delim = gDirUtilp->getDirDelimiter();
|
||||
std::list<std::string>::iterator in_file = input_filenames.begin();
|
||||
std::list<std::string>::iterator end = input_filenames.end();
|
||||
for (; in_file != end; ++in_file)
|
||||
{
|
||||
dir = gDirUtilp->getDirName(*in_file);
|
||||
name = gDirUtilp->getBaseFileName(*in_file,true);
|
||||
std::string file_name;
|
||||
if (!dir.empty())
|
||||
{
|
||||
file_name = dir + delim + name + "." + exten;
|
||||
}
|
||||
else
|
||||
{
|
||||
file_name = name + "." + exten;
|
||||
}
|
||||
output_filenames.push_back(file_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure the extension is an image type
|
||||
if (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Store the path
|
||||
output_filenames.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
// Holds the metric gathering output in a thread safe way
|
||||
class LogThread : public LLThread
|
||||
{
|
||||
public:
|
||||
std::string mFile;
|
||||
|
||||
LogThread(std::string& test_name) : LLThread("llimage_libtest log")
|
||||
{
|
||||
std::string file_name = test_name + std::string(".slp");
|
||||
mFile = file_name;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
std::ofstream os(mFile.c_str());
|
||||
|
||||
while (!sAllDone)
|
||||
{
|
||||
LLFastTimer::writeLog(os);
|
||||
os.flush();
|
||||
ms_sleep(32);
|
||||
}
|
||||
LLFastTimer::writeLog(os);
|
||||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// List of input and output files
|
||||
std::list<std::string> input_filenames;
|
||||
std::list<std::string> output_filenames;
|
||||
bool analyze_performance = false;
|
||||
bool image_stats = false;
|
||||
|
||||
// Init whatever is necessary
|
||||
ll_init_apr();
|
||||
LLImage::initClass();
|
||||
LogThread* fast_timer_log_thread = NULL; // For performance and metric gathering
|
||||
|
||||
// Analyze command line arguments
|
||||
for (int arg = 1; arg < argc; ++arg)
|
||||
{
|
||||
if (!strcmp(argv[arg], "--help") || !strcmp(argv[arg], "-h"))
|
||||
{
|
||||
// Send the usage to standard out
|
||||
std::cout << USAGE << std::endl;
|
||||
return 0;
|
||||
}
|
||||
else if ((!strcmp(argv[arg], "--input") || !strcmp(argv[arg], "-i")) && arg < argc-1)
|
||||
{
|
||||
std::string file_name = argv[arg+1];
|
||||
while (file_name[0] != '-') // if arg starts with '-', we consider it's not a file name but some other argument
|
||||
{
|
||||
// std::cout << "input file name : " << file_name << std::endl;
|
||||
store_input_file(input_filenames, file_name);
|
||||
arg += 1; // Skip that arg now we know it's a file name
|
||||
if ((arg + 1) == argc) // Break out of the loop if we reach the end of the arg list
|
||||
break;
|
||||
file_name = argv[arg+1]; // Next argument and loop over
|
||||
}
|
||||
}
|
||||
else if ((!strcmp(argv[arg], "--output") || !strcmp(argv[arg], "-o")) && arg < argc-1)
|
||||
{
|
||||
std::string file_name = argv[arg+1];
|
||||
while (file_name[0] != '-') // if arg starts with '-', we consider it's not a file name but some other argument
|
||||
{
|
||||
// std::cout << "output file name : " << file_name << std::endl;
|
||||
store_output_file(output_filenames, input_filenames, file_name);
|
||||
arg += 1; // Skip that arg now we know it's a file name
|
||||
if ((arg + 1) == argc) // Break out of the loop if we reach the end of the arg list
|
||||
break;
|
||||
file_name = argv[arg+1]; // Next argument and loop over
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[arg], "--logmetrics") || !strcmp(argv[arg], "-log"))
|
||||
{
|
||||
// '--logmetrics' needs to be specified with a named test metric argument
|
||||
// Note: for the moment, only ImageCompressionTester has been tested
|
||||
std::string test_name;
|
||||
if ((arg + 1) < argc)
|
||||
{
|
||||
test_name = argv[arg+1];
|
||||
}
|
||||
if (((arg + 1) >= argc) || (test_name[0] == '-'))
|
||||
{
|
||||
// We don't have an argument left in the arg list or the next argument is another option
|
||||
std::cout << "No --logmetrics argument given, no perf data will be gathered" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFastTimer::sMetricLog = TRUE;
|
||||
LLFastTimer::sLogName = test_name;
|
||||
arg += 1; // Skip that arg now we know it's a valid test name
|
||||
if ((arg + 1) == argc) // Break out of the loop if we reach the end of the arg list
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-r"))
|
||||
{
|
||||
analyze_performance = true;
|
||||
}
|
||||
else if (!strcmp(argv[arg], "--image-stats") || !strcmp(argv[arg], "-s"))
|
||||
{
|
||||
image_stats = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check arguments consistency. Exit with proper message if inconsistent.
|
||||
if (input_filenames.size() == 0)
|
||||
{
|
||||
std::cout << "No input file, nothing to do -> exit" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
if (analyze_performance && !LLFastTimer::sMetricLog)
|
||||
{
|
||||
std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -r) -> exit" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Create the logging thread if required
|
||||
if (LLFastTimer::sMetricLog)
|
||||
{
|
||||
LLFastTimer::sLogLock = new LLMutex(NULL);
|
||||
fast_timer_log_thread = new LogThread(LLFastTimer::sLogName);
|
||||
fast_timer_log_thread->start();
|
||||
}
|
||||
|
||||
// Perform action on each input file
|
||||
std::list<std::string>::iterator in_file = input_filenames.begin();
|
||||
std::list<std::string>::iterator out_file = output_filenames.begin();
|
||||
std::list<std::string>::iterator in_end = input_filenames.end();
|
||||
std::list<std::string>::iterator out_end = output_filenames.end();
|
||||
for (; in_file != in_end; ++in_file)
|
||||
{
|
||||
// Load file
|
||||
LLPointer<LLImageRaw> raw_image = load_image(*in_file, image_stats);
|
||||
if (!raw_image)
|
||||
{
|
||||
std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Save file
|
||||
if (out_file != out_end)
|
||||
{
|
||||
if (!save_image(*out_file, raw_image, image_stats))
|
||||
{
|
||||
std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << *in_file << " -> " << *out_file << std::endl;
|
||||
}
|
||||
++out_file;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the perf gathering system if needed
|
||||
if (LLFastTimer::sMetricLog)
|
||||
{
|
||||
LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName);
|
||||
sAllDone = true;
|
||||
}
|
||||
|
||||
// Output perf data if requested by user
|
||||
if (analyze_performance)
|
||||
{
|
||||
std::cout << "Analyzing performance" << std::endl;
|
||||
|
||||
std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
|
||||
std::string current_name = LLFastTimer::sLogName + ".slp";
|
||||
std::string report_name = LLFastTimer::sLogName + "_report.csv";
|
||||
|
||||
LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name);
|
||||
}
|
||||
|
||||
// Cleanup and exit
|
||||
LLImage::cleanupClass();
|
||||
if (fast_timer_log_thread)
|
||||
{
|
||||
fast_timer_log_thread->shutdown();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @file llimage_libtest.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#ifndef LLIMAGE_LIBTEST_H
|
||||
#define LLIMAGE_LIBTEST_H
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -91,14 +91,14 @@ if (WINDOWS)
|
|||
# Copy over OpenJPEG.dll
|
||||
# *NOTE: On Windows with VS2005, only the first comment prints
|
||||
set(OPENJPEG_RELEASE
|
||||
"${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release/openjpeg.dll")
|
||||
"${ARCH_PREBUILT_DIRS_RELEASE}/openjpeg.dll")
|
||||
add_custom_command( TARGET llui_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${OPENJPEG_RELEASE} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Copying OpenJPEG DLLs to binary directory"
|
||||
)
|
||||
set(OPENJPEG_DEBUG
|
||||
"${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug/openjpegd.dll")
|
||||
"${ARCH_PREBUILT_DIRS_DEBUG}/openjpegd.dll")
|
||||
add_custom_command( TARGET llui_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${OPENJPEG_DEBUG} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ include_directories(
|
|||
${VORBIS_INCLUDE_DIRS}
|
||||
${OPENAL_LIB_INCLUDE_DIRS}
|
||||
${FREEAULT_LIB_INCLUDE_DIRS}
|
||||
${FMOD_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(llaudio_SOURCE_FILES
|
||||
|
|
|
|||
|
|
@ -680,4 +680,10 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#if LL_DARWIN || LL_LINUX
|
||||
// HACK: to fool the compiler into not emitting unused warnings.
|
||||
namespace {
|
||||
const ov_callbacks callback_array[4] = {OV_CALLBACKS_DEFAULT, OV_CALLBACKS_NOCLOSE, OV_CALLBACKS_STREAMONLY,
|
||||
OV_CALLBACKS_STREAMONLY_NOCLOSE};
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include "lllistener_openal.h"
|
||||
|
||||
|
||||
const float LLAudioEngine_OpenAL::WIND_BUFFER_SIZE_SEC = 0.05f;
|
||||
|
||||
LLAudioEngine_OpenAL::LLAudioEngine_OpenAL()
|
||||
:
|
||||
mWindGen(NULL),
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class LLAudioEngine_OpenAL : public LLAudioEngine
|
|||
int mNumEmptyWindALBuffers;
|
||||
|
||||
static const int MAX_NUM_WIND_BUFFERS = 80;
|
||||
static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec
|
||||
static const float WIND_BUFFER_SIZE_SEC; // 1/20th sec
|
||||
};
|
||||
|
||||
class LLAudioChannelOpenAL : public LLAudioChannel
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ include(LLSharedLibs)
|
|||
include(GoogleBreakpad)
|
||||
include(GooglePerfTools)
|
||||
include(Copy3rdPartyLibs)
|
||||
include(ZLIB)
|
||||
|
||||
include_directories(
|
||||
${EXPAT_INCLUDE_DIRS}
|
||||
|
|
@ -62,6 +63,7 @@ set(llcommon_SOURCE_FILES
|
|||
llformat.cpp
|
||||
llframetimer.cpp
|
||||
llheartbeat.cpp
|
||||
llinstancetracker.cpp
|
||||
llliveappconfig.cpp
|
||||
lllivefile.cpp
|
||||
lllog.cpp
|
||||
|
|
@ -313,6 +315,7 @@ if (LL_TESTS)
|
|||
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
|
||||
LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}")
|
||||
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
|
||||
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
|
||||
|
||||
# *TODO - reenable these once tcmalloc libs no longer break the build.
|
||||
#ADD_BUILD_TEST(llallocator llcommon)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,354 @@
|
|||
#include "llevents.h"
|
||||
#include "llerror.h"
|
||||
#include "llsdutil.h"
|
||||
#include "stringize.h"
|
||||
#include <memory> // std::auto_ptr
|
||||
|
||||
/*****************************************************************************
|
||||
* LLSDArgsSource
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* Store an LLSD array, producing its elements one at a time. Die with LL_ERRS
|
||||
* if the consumer requests more elements than the array contains.
|
||||
*/
|
||||
class LL_COMMON_API LLSDArgsSource
|
||||
{
|
||||
public:
|
||||
LLSDArgsSource(const std::string function, const LLSD& args);
|
||||
~LLSDArgsSource();
|
||||
|
||||
LLSD next();
|
||||
|
||||
void done() const;
|
||||
|
||||
private:
|
||||
std::string _function;
|
||||
LLSD _args;
|
||||
LLSD::Integer _index;
|
||||
};
|
||||
|
||||
LLSDArgsSource::LLSDArgsSource(const std::string function, const LLSD& args):
|
||||
_function(function),
|
||||
_args(args),
|
||||
_index(0)
|
||||
{
|
||||
if (! (_args.isUndefined() || _args.isArray()))
|
||||
{
|
||||
LL_ERRS("LLSDArgsSource") << _function << " needs an args array instead of "
|
||||
<< _args << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
LLSDArgsSource::~LLSDArgsSource()
|
||||
{
|
||||
done();
|
||||
}
|
||||
|
||||
LLSD LLSDArgsSource::next()
|
||||
{
|
||||
if (_index >= _args.size())
|
||||
{
|
||||
LL_ERRS("LLSDArgsSource") << _function << " requires more arguments than the "
|
||||
<< _args.size() << " provided: " << _args << LL_ENDL;
|
||||
}
|
||||
return _args[_index++];
|
||||
}
|
||||
|
||||
void LLSDArgsSource::done() const
|
||||
{
|
||||
if (_index < _args.size())
|
||||
{
|
||||
LL_WARNS("LLSDArgsSource") << _function << " only consumed " << _index
|
||||
<< " of the " << _args.size() << " arguments provided: "
|
||||
<< _args << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* LLSDArgsMapper
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* From a formal parameters description and a map of arguments, construct an
|
||||
* arguments array.
|
||||
*
|
||||
* That is, given:
|
||||
* - an LLSD array of length n containing parameter-name strings,
|
||||
* corresponding to the arguments of a function of interest
|
||||
* - an LLSD collection specifying default parameter values, either:
|
||||
* - an LLSD array of length m <= n, matching the rightmost m params, or
|
||||
* - an LLSD map explicitly stating default name=value pairs
|
||||
* - an LLSD map of parameter names and actual values for a particular
|
||||
* function call
|
||||
* construct an LLSD array of actual argument values for this function call.
|
||||
*
|
||||
* The parameter-names array and the defaults collection describe the function
|
||||
* being called. The map might vary with every call, providing argument values
|
||||
* for the described parameters.
|
||||
*
|
||||
* The array of parameter names must match the number of parameters expected
|
||||
* by the function of interest.
|
||||
*
|
||||
* If you pass a map of default parameter values, it provides default values
|
||||
* as you might expect. It is an error to specify a default value for a name
|
||||
* not listed in the parameters array.
|
||||
*
|
||||
* If you pass an array of default parameter values, it is mapped to the
|
||||
* rightmost m of the n parameter names. It is an error if the default-values
|
||||
* array is longer than the parameter-names array. Consider the following
|
||||
* parameter names: ["a", "b", "c", "d"].
|
||||
*
|
||||
* - An empty array of default values (or an isUndefined() value) asserts that
|
||||
* every one of the above parameter names is required.
|
||||
* - An array of four default values [1, 2, 3, 4] asserts that every one of
|
||||
* the above parameters is optional. If the current parameter map is empty,
|
||||
* they will be passed to the function as [1, 2, 3, 4].
|
||||
* - An array of two default values [11, 12] asserts that parameters "a" and
|
||||
* "b" are required, while "c" and "d" are optional, having default values
|
||||
* "c"=11 and "d"=12.
|
||||
*
|
||||
* The arguments array is constructed as follows:
|
||||
*
|
||||
* - Arguments-map keys not found in the parameter-names array are ignored.
|
||||
* - Entries from the map provide values for an improper subset of the
|
||||
* parameters named in the parameter-names array. This results in a
|
||||
* tentative values array with "holes." (size of map) + (number of holes) =
|
||||
* (size of names array)
|
||||
* - Holes are filled with the default values.
|
||||
* - Any remaining holes constitute an error.
|
||||
*/
|
||||
class LL_COMMON_API LLSDArgsMapper
|
||||
{
|
||||
public:
|
||||
/// Accept description of function: function name, param names, param
|
||||
/// default values
|
||||
LLSDArgsMapper(const std::string& function, const LLSD& names, const LLSD& defaults);
|
||||
|
||||
/// Given arguments map, return LLSD::Array of parameter values, or LL_ERRS.
|
||||
LLSD map(const LLSD& argsmap) const;
|
||||
|
||||
private:
|
||||
static std::string formatlist(const LLSD&);
|
||||
|
||||
// The function-name string is purely descriptive. We want error messages
|
||||
// to be able to indicate which function's LLSDArgsMapper has the problem.
|
||||
std::string _function;
|
||||
// Store the names array pretty much as given.
|
||||
LLSD _names;
|
||||
// Though we're handed an array of name strings, it's more useful to us to
|
||||
// store it as a map from name string to position index. Of course that's
|
||||
// easy to generate from the incoming names array, but why do it more than
|
||||
// once?
|
||||
typedef std::map<LLSD::String, LLSD::Integer> IndexMap;
|
||||
IndexMap _indexes;
|
||||
// Generated array of default values, aligned with the array of param names.
|
||||
LLSD _defaults;
|
||||
// Indicate whether we have a default value for each param.
|
||||
typedef std::vector<char> FilledVector;
|
||||
FilledVector _has_dft;
|
||||
};
|
||||
|
||||
LLSDArgsMapper::LLSDArgsMapper(const std::string& function,
|
||||
const LLSD& names, const LLSD& defaults):
|
||||
_function(function),
|
||||
_names(names),
|
||||
_has_dft(names.size())
|
||||
{
|
||||
if (! (_names.isUndefined() || _names.isArray()))
|
||||
{
|
||||
LL_ERRS("LLSDArgsMapper") << function << " names must be an array, not " << names << LL_ENDL;
|
||||
}
|
||||
LLSD::Integer nparams(_names.size());
|
||||
// From _names generate _indexes.
|
||||
for (LLSD::Integer ni = 0, nend = _names.size(); ni < nend; ++ni)
|
||||
{
|
||||
_indexes[_names[ni]] = ni;
|
||||
}
|
||||
|
||||
// Presize _defaults() array so we don't have to resize it more than once.
|
||||
// All entries are initialized to LLSD(); but since _has_dft is still all
|
||||
// 0, they're all "holes" for now.
|
||||
if (nparams)
|
||||
{
|
||||
_defaults[nparams - 1] = LLSD();
|
||||
}
|
||||
|
||||
if (defaults.isUndefined() || defaults.isArray())
|
||||
{
|
||||
LLSD::Integer ndefaults = defaults.size();
|
||||
// defaults is a (possibly empty) array. Right-align it with names.
|
||||
if (ndefaults > nparams)
|
||||
{
|
||||
LL_ERRS("LLSDArgsMapper") << function << " names array " << names
|
||||
<< " shorter than defaults array " << defaults << LL_ENDL;
|
||||
}
|
||||
|
||||
// Offset by which we slide defaults array right to right-align with
|
||||
// _names array
|
||||
LLSD::Integer offset = nparams - ndefaults;
|
||||
// Fill rightmost _defaults entries from defaults, and mark them as
|
||||
// filled
|
||||
for (LLSD::Integer i = 0, iend = ndefaults; i < iend; ++i)
|
||||
{
|
||||
_defaults[i + offset] = defaults[i];
|
||||
_has_dft[i + offset] = 1;
|
||||
}
|
||||
}
|
||||
else if (defaults.isMap())
|
||||
{
|
||||
// defaults is a map. Use it to populate the _defaults array.
|
||||
LLSD bogus;
|
||||
for (LLSD::map_const_iterator mi(defaults.beginMap()), mend(defaults.endMap());
|
||||
mi != mend; ++mi)
|
||||
{
|
||||
IndexMap::const_iterator ixit(_indexes.find(mi->first));
|
||||
if (ixit == _indexes.end())
|
||||
{
|
||||
bogus.append(mi->first);
|
||||
continue;
|
||||
}
|
||||
|
||||
LLSD::Integer pos = ixit->second;
|
||||
// Store default value at that position in the _defaults array.
|
||||
_defaults[pos] = mi->second;
|
||||
// Don't forget to record the fact that we've filled this
|
||||
// position.
|
||||
_has_dft[pos] = 1;
|
||||
}
|
||||
if (bogus.size())
|
||||
{
|
||||
LL_ERRS("LLSDArgsMapper") << function << " defaults specified for nonexistent params "
|
||||
<< formatlist(bogus) << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_ERRS("LLSDArgsMapper") << function << " defaults must be a map or an array, not "
|
||||
<< defaults << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
LLSD LLSDArgsMapper::map(const LLSD& argsmap) const
|
||||
{
|
||||
if (! (argsmap.isUndefined() || argsmap.isMap() || argsmap.isArray()))
|
||||
{
|
||||
LL_ERRS("LLSDArgsMapper") << _function << " map() needs a map or array, not "
|
||||
<< argsmap << LL_ENDL;
|
||||
}
|
||||
// Initialize the args array. Indexing a non-const LLSD array grows it
|
||||
// to appropriate size, but we don't want to resize this one on each
|
||||
// new operation. Just make it as big as we need before we start
|
||||
// stuffing values into it.
|
||||
LLSD args(LLSD::emptyArray());
|
||||
if (_defaults.size() == 0)
|
||||
{
|
||||
// If this function requires no arguments, fast exit. (Don't try to
|
||||
// assign to args[-1].)
|
||||
return args;
|
||||
}
|
||||
args[_defaults.size() - 1] = LLSD();
|
||||
|
||||
// Get a vector of chars to indicate holes. It's tempting to just scan
|
||||
// for LLSD::isUndefined() values after filling the args array from
|
||||
// the map, but it's plausible for caller to explicitly pass
|
||||
// isUndefined() as the value of some parameter name. That's legal
|
||||
// since isUndefined() has well-defined conversions (default value)
|
||||
// for LLSD data types. So use a whole separate array for detecting
|
||||
// holes. (Avoid std::vector<bool> which is known to be odd -- can we
|
||||
// iterate?)
|
||||
FilledVector filled(args.size());
|
||||
|
||||
if (argsmap.isArray())
|
||||
{
|
||||
// Fill args from array. If there are too many args in passed array,
|
||||
// ignore the rest.
|
||||
LLSD::Integer size(argsmap.size());
|
||||
if (size > args.size())
|
||||
{
|
||||
// We don't just use std::min() because we want to sneak in this
|
||||
// warning if caller passes too many args.
|
||||
LL_WARNS("LLSDArgsMapper") << _function << " needs " << args.size()
|
||||
<< " params, ignoring last " << (size - args.size())
|
||||
<< " of passed " << size << ": " << argsmap << LL_ENDL;
|
||||
size = args.size();
|
||||
}
|
||||
for (LLSD::Integer i(0); i < size; ++i)
|
||||
{
|
||||
// Copy the actual argument from argsmap
|
||||
args[i] = argsmap[i];
|
||||
// Note that it's been filled
|
||||
filled[i] = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// argsmap is in fact a map. Walk the map.
|
||||
for (LLSD::map_const_iterator mi(argsmap.beginMap()), mend(argsmap.endMap());
|
||||
mi != mend; ++mi)
|
||||
{
|
||||
// mi->first is a parameter-name string, with mi->second its
|
||||
// value. Look up the name's position index in _indexes.
|
||||
IndexMap::const_iterator ixit(_indexes.find(mi->first));
|
||||
if (ixit == _indexes.end())
|
||||
{
|
||||
// Allow for a map containing more params than were passed in
|
||||
// our names array. Caller typically receives a map containing
|
||||
// the function name, cruft such as reqid, etc. Ignore keys
|
||||
// not defined in _indexes.
|
||||
LL_DEBUGS("LLSDArgsMapper") << _function << " ignoring "
|
||||
<< mi->first << "=" << mi->second << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
LLSD::Integer pos = ixit->second;
|
||||
// Store the value at that position in the args array.
|
||||
args[pos] = mi->second;
|
||||
// Don't forget to record the fact that we've filled this
|
||||
// position.
|
||||
filled[pos] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill any remaining holes from _defaults.
|
||||
LLSD unfilled(LLSD::emptyArray());
|
||||
for (LLSD::Integer i = 0, iend = args.size(); i < iend; ++i)
|
||||
{
|
||||
if (! filled[i])
|
||||
{
|
||||
// If there's no default value for this parameter, that's an
|
||||
// error.
|
||||
if (! _has_dft[i])
|
||||
{
|
||||
unfilled.append(_names[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
args[i] = _defaults[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// If any required args -- args without defaults -- were left unfilled
|
||||
// by argsmap, that's a problem.
|
||||
if (unfilled.size())
|
||||
{
|
||||
LL_ERRS("LLSDArgsMapper") << _function << " missing required arguments "
|
||||
<< formatlist(unfilled) << " from " << argsmap << LL_ENDL;
|
||||
}
|
||||
|
||||
// done
|
||||
return args;
|
||||
}
|
||||
|
||||
std::string LLSDArgsMapper::formatlist(const LLSD& list)
|
||||
{
|
||||
std::ostringstream out;
|
||||
const char* delim = "";
|
||||
for (LLSD::array_const_iterator li(list.beginArray()), lend(list.endArray());
|
||||
li != lend; ++li)
|
||||
{
|
||||
out << delim << li->asString();
|
||||
delim = ", ";
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
LLEventDispatcher::LLEventDispatcher(const std::string& desc, const std::string& key):
|
||||
mDesc(desc),
|
||||
|
|
@ -52,12 +400,181 @@ LLEventDispatcher::~LLEventDispatcher()
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* DispatchEntry subclass used for callables accepting(const LLSD&)
|
||||
*/
|
||||
struct LLEventDispatcher::LLSDDispatchEntry: public LLEventDispatcher::DispatchEntry
|
||||
{
|
||||
LLSDDispatchEntry(const std::string& desc, const Callable& func, const LLSD& required):
|
||||
DispatchEntry(desc),
|
||||
mFunc(func),
|
||||
mRequired(required)
|
||||
{}
|
||||
|
||||
Callable mFunc;
|
||||
LLSD mRequired;
|
||||
|
||||
virtual void call(const std::string& desc, const LLSD& event) const
|
||||
{
|
||||
// Validate the syntax of the event itself.
|
||||
std::string mismatch(llsd_matches(mRequired, event));
|
||||
if (! mismatch.empty())
|
||||
{
|
||||
LL_ERRS("LLEventDispatcher") << desc << ": bad request: " << mismatch << LL_ENDL;
|
||||
}
|
||||
// Event syntax looks good, go for it!
|
||||
mFunc(event);
|
||||
}
|
||||
|
||||
virtual LLSD addMetadata(LLSD meta) const
|
||||
{
|
||||
meta["required"] = mRequired;
|
||||
return meta;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* DispatchEntry subclass for passing LLSD to functions accepting
|
||||
* arbitrary argument types (convertible via LLSDParam)
|
||||
*/
|
||||
struct LLEventDispatcher::ParamsDispatchEntry: public LLEventDispatcher::DispatchEntry
|
||||
{
|
||||
ParamsDispatchEntry(const std::string& desc, const invoker_function& func):
|
||||
DispatchEntry(desc),
|
||||
mInvoker(func)
|
||||
{}
|
||||
|
||||
invoker_function mInvoker;
|
||||
|
||||
virtual void call(const std::string& desc, const LLSD& event) const
|
||||
{
|
||||
LLSDArgsSource src(desc, event);
|
||||
mInvoker(boost::bind(&LLSDArgsSource::next, boost::ref(src)));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* DispatchEntry subclass for dispatching LLSD::Array to functions accepting
|
||||
* arbitrary argument types (convertible via LLSDParam)
|
||||
*/
|
||||
struct LLEventDispatcher::ArrayParamsDispatchEntry: public LLEventDispatcher::ParamsDispatchEntry
|
||||
{
|
||||
ArrayParamsDispatchEntry(const std::string& desc, const invoker_function& func,
|
||||
LLSD::Integer arity):
|
||||
ParamsDispatchEntry(desc, func),
|
||||
mArity(arity)
|
||||
{}
|
||||
|
||||
LLSD::Integer mArity;
|
||||
|
||||
virtual LLSD addMetadata(LLSD meta) const
|
||||
{
|
||||
LLSD array(LLSD::emptyArray());
|
||||
// Resize to number of arguments required
|
||||
if (mArity)
|
||||
array[mArity - 1] = LLSD();
|
||||
llassert_always(array.size() == mArity);
|
||||
meta["required"] = array;
|
||||
return meta;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* DispatchEntry subclass for dispatching LLSD::Map to functions accepting
|
||||
* arbitrary argument types (convertible via LLSDParam)
|
||||
*/
|
||||
struct LLEventDispatcher::MapParamsDispatchEntry: public LLEventDispatcher::ParamsDispatchEntry
|
||||
{
|
||||
MapParamsDispatchEntry(const std::string& name, const std::string& desc,
|
||||
const invoker_function& func,
|
||||
const LLSD& params, const LLSD& defaults):
|
||||
ParamsDispatchEntry(desc, func),
|
||||
mMapper(name, params, defaults),
|
||||
mRequired(LLSD::emptyMap())
|
||||
{
|
||||
// Build the set of all param keys, then delete the ones that are
|
||||
// optional. What's left are the ones that are required.
|
||||
for (LLSD::array_const_iterator pi(params.beginArray()), pend(params.endArray());
|
||||
pi != pend; ++pi)
|
||||
{
|
||||
mRequired[pi->asString()] = LLSD();
|
||||
}
|
||||
|
||||
if (defaults.isArray() || defaults.isUndefined())
|
||||
{
|
||||
// Right-align the params and defaults arrays.
|
||||
LLSD::Integer offset = params.size() - defaults.size();
|
||||
// Now the name of every defaults[i] is at params[i + offset].
|
||||
for (LLSD::Integer i(0), iend(defaults.size()); i < iend; ++i)
|
||||
{
|
||||
// Erase this optional param from mRequired.
|
||||
mRequired.erase(params[i + offset].asString());
|
||||
// Instead, make an entry in mOptional with the default
|
||||
// param's name and value.
|
||||
mOptional[params[i + offset].asString()] = defaults[i];
|
||||
}
|
||||
}
|
||||
else if (defaults.isMap())
|
||||
{
|
||||
// if defaults is already a map, then it's already in the form we
|
||||
// intend to deliver in metadata
|
||||
mOptional = defaults;
|
||||
// Just delete from mRequired every key appearing in mOptional.
|
||||
for (LLSD::map_const_iterator mi(mOptional.beginMap()), mend(mOptional.endMap());
|
||||
mi != mend; ++mi)
|
||||
{
|
||||
mRequired.erase(mi->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLSDArgsMapper mMapper;
|
||||
LLSD mRequired;
|
||||
LLSD mOptional;
|
||||
|
||||
virtual void call(const std::string& desc, const LLSD& event) const
|
||||
{
|
||||
// Just convert from LLSD::Map to LLSD::Array using mMapper, then pass
|
||||
// to base-class call() method.
|
||||
ParamsDispatchEntry::call(desc, mMapper.map(event));
|
||||
}
|
||||
|
||||
virtual LLSD addMetadata(LLSD meta) const
|
||||
{
|
||||
meta["required"] = mRequired;
|
||||
meta["optional"] = mOptional;
|
||||
return meta;
|
||||
}
|
||||
};
|
||||
|
||||
void LLEventDispatcher::addArrayParamsDispatchEntry(const std::string& name,
|
||||
const std::string& desc,
|
||||
const invoker_function& invoker,
|
||||
LLSD::Integer arity)
|
||||
{
|
||||
mDispatch.insert(
|
||||
DispatchMap::value_type(name, DispatchMap::mapped_type(
|
||||
new ArrayParamsDispatchEntry(desc, invoker, arity))));
|
||||
}
|
||||
|
||||
void LLEventDispatcher::addMapParamsDispatchEntry(const std::string& name,
|
||||
const std::string& desc,
|
||||
const invoker_function& invoker,
|
||||
const LLSD& params,
|
||||
const LLSD& defaults)
|
||||
{
|
||||
mDispatch.insert(
|
||||
DispatchMap::value_type(name, DispatchMap::mapped_type(
|
||||
new MapParamsDispatchEntry(name, desc, invoker, params, defaults))));
|
||||
}
|
||||
|
||||
/// Register a callable by name
|
||||
void LLEventDispatcher::add(const std::string& name, const std::string& desc,
|
||||
const Callable& callable, const LLSD& required)
|
||||
{
|
||||
mDispatch.insert(DispatchMap::value_type(name,
|
||||
DispatchMap::mapped_type(callable, desc, required)));
|
||||
mDispatch.insert(
|
||||
DispatchMap::value_type(name, DispatchMap::mapped_type(
|
||||
new LLSDDispatchEntry(desc, callable, required))));
|
||||
}
|
||||
|
||||
void LLEventDispatcher::addFail(const std::string& name, const std::string& classname) const
|
||||
|
|
@ -83,7 +600,7 @@ bool LLEventDispatcher::remove(const std::string& name)
|
|||
/// such callable exists, die with LL_ERRS.
|
||||
void LLEventDispatcher::operator()(const std::string& name, const LLSD& event) const
|
||||
{
|
||||
if (! attemptCall(name, event))
|
||||
if (! try_call(name, event))
|
||||
{
|
||||
LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << "): '" << name
|
||||
<< "' not found" << LL_ENDL;
|
||||
|
|
@ -98,44 +615,29 @@ void LLEventDispatcher::operator()(const LLSD& event) const
|
|||
// This could/should be implemented in terms of the two-arg overload.
|
||||
// However -- we can produce a more informative error message.
|
||||
std::string name(event[mKey]);
|
||||
if (! attemptCall(name, event))
|
||||
if (! try_call(name, event))
|
||||
{
|
||||
LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << "): bad " << mKey
|
||||
<< " value '" << name << "'" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLEventDispatcher::attemptCall(const std::string& name, const LLSD& event) const
|
||||
bool LLEventDispatcher::try_call(const LLSD& event) const
|
||||
{
|
||||
DispatchMap::const_iterator found = mDispatch.find(name);
|
||||
if (found == mDispatch.end())
|
||||
{
|
||||
// The reason we only return false, leaving it up to our caller to die
|
||||
// with LL_ERRS, is that different callers have different amounts of
|
||||
// available information.
|
||||
return false;
|
||||
}
|
||||
// Found the name, so it's plausible to even attempt the call. But first,
|
||||
// validate the syntax of the event itself.
|
||||
std::string mismatch(llsd_matches(found->second.mRequired, event));
|
||||
if (! mismatch.empty())
|
||||
{
|
||||
LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << ") calling '" << name
|
||||
<< "': bad request: " << mismatch << LL_ENDL;
|
||||
}
|
||||
// Event syntax looks good, go for it!
|
||||
(found->second.mFunc)(event);
|
||||
return true; // tell caller we were able to call
|
||||
return try_call(event[mKey], event);
|
||||
}
|
||||
|
||||
LLEventDispatcher::Callable LLEventDispatcher::get(const std::string& name) const
|
||||
bool LLEventDispatcher::try_call(const std::string& name, const LLSD& event) const
|
||||
{
|
||||
DispatchMap::const_iterator found = mDispatch.find(name);
|
||||
if (found == mDispatch.end())
|
||||
{
|
||||
return Callable();
|
||||
return false;
|
||||
}
|
||||
return found->second.mFunc;
|
||||
// Found the name, so it's plausible to even attempt the call.
|
||||
found->second->call(STRINGIZE("LLEventDispatcher(" << mDesc << ") calling '" << name << "'"),
|
||||
event);
|
||||
return true; // tell caller we were able to call
|
||||
}
|
||||
|
||||
LLSD LLEventDispatcher::getMetadata(const std::string& name) const
|
||||
|
|
@ -147,9 +649,8 @@ LLSD LLEventDispatcher::getMetadata(const std::string& name) const
|
|||
}
|
||||
LLSD meta;
|
||||
meta["name"] = name;
|
||||
meta["desc"] = found->second.mDesc;
|
||||
meta["required"] = found->second.mRequired;
|
||||
return meta;
|
||||
meta["desc"] = found->second->mDesc;
|
||||
return found->second->addMetadata(meta);
|
||||
}
|
||||
|
||||
LLDispatchListener::LLDispatchListener(const std::string& pumpname, const std::string& key):
|
||||
|
|
@ -164,3 +665,8 @@ bool LLDispatchListener::process(const LLSD& event)
|
|||
(*this)(event);
|
||||
return false;
|
||||
}
|
||||
|
||||
LLEventDispatcher::DispatchEntry::DispatchEntry(const std::string& desc):
|
||||
mDesc(desc)
|
||||
{}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,18 +27,56 @@
|
|||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*
|
||||
* The invoker machinery that constructs a boost::fusion argument list for use
|
||||
* with boost::fusion::invoke() is derived from
|
||||
* http://www.boost.org/doc/libs/1_45_0/libs/function_types/example/interpreter.hpp
|
||||
* whose license information is copied below:
|
||||
*
|
||||
* "(C) Copyright Tobias Schwinger
|
||||
*
|
||||
* Use modification and distribution are subject to the boost Software License,
|
||||
* Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt)."
|
||||
*/
|
||||
|
||||
#if ! defined(LL_LLEVENTDISPATCHER_H)
|
||||
#define LL_LLEVENTDISPATCHER_H
|
||||
|
||||
// nil is too generic a term to be allowed to be a global macro. In
|
||||
// particular, boost::fusion defines a 'class nil' (properly encapsulated in a
|
||||
// namespace) that a global 'nil' macro breaks badly.
|
||||
#if defined(nil)
|
||||
// Capture the value of the macro 'nil', hoping int is an appropriate type.
|
||||
static const int nil_(nil);
|
||||
// Now forget the macro.
|
||||
#undef nil
|
||||
// Finally, reintroduce 'nil' as a properly-scoped alias for the previously-
|
||||
// defined const 'nil_'. Make it static since otherwise it produces duplicate-
|
||||
// symbol link errors later.
|
||||
static const int& nil(nil_);
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/function_types/is_nonmember_callable_builtin.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/function_types/function_arity.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/fusion/include/push_back.hpp>
|
||||
#include <boost/fusion/include/cons.hpp>
|
||||
#include <boost/fusion/include/invoke.hpp>
|
||||
#include <boost/mpl/begin.hpp>
|
||||
#include <boost/mpl/end.hpp>
|
||||
#include <boost/mpl/next.hpp>
|
||||
#include <boost/mpl/deref.hpp>
|
||||
#include <typeinfo>
|
||||
#include "llevents.h"
|
||||
#include "llsdutil.h"
|
||||
|
||||
class LLSD;
|
||||
|
||||
|
|
@ -54,12 +92,18 @@ public:
|
|||
LLEventDispatcher(const std::string& desc, const std::string& key);
|
||||
virtual ~LLEventDispatcher();
|
||||
|
||||
/// Accept any C++ callable, typically a boost::bind() expression
|
||||
/// @name Register functions accepting(const LLSD&)
|
||||
//@{
|
||||
|
||||
/// Accept any C++ callable with the right signature, typically a
|
||||
/// boost::bind() expression
|
||||
typedef boost::function<void(const LLSD&)> Callable;
|
||||
|
||||
/**
|
||||
* Register a @a callable by @a name. The optional @a required parameter
|
||||
* is used to validate the structure of each incoming event (see
|
||||
* Register a @a callable by @a name. The passed @a callable accepts a
|
||||
* single LLSD value and uses it in any way desired, e.g. extract
|
||||
* parameters and call some other function. The optional @a required
|
||||
* parameter is used to validate the structure of each incoming event (see
|
||||
* llsd_matches()).
|
||||
*/
|
||||
void add(const std::string& name,
|
||||
|
|
@ -67,10 +111,24 @@ public:
|
|||
const Callable& callable,
|
||||
const LLSD& required=LLSD());
|
||||
|
||||
/**
|
||||
* The case of a free function (or static method) accepting(const LLSD&)
|
||||
* could also be intercepted by the arbitrary-args overload below. Ensure
|
||||
* that it's directed to the Callable overload above instead.
|
||||
*/
|
||||
void add(const std::string& name,
|
||||
const std::string& desc,
|
||||
void (*f)(const LLSD&),
|
||||
const LLSD& required=LLSD())
|
||||
{
|
||||
add(name, desc, Callable(f), required);
|
||||
}
|
||||
|
||||
/**
|
||||
* Special case: a subclass of this class can pass an unbound member
|
||||
* function pointer without explicitly specifying the
|
||||
* <tt>boost::bind()</tt> expression.
|
||||
* function pointer (of an LLEventDispatcher subclass) without explicitly
|
||||
* specifying the <tt>boost::bind()</tt> expression. The passed @a method
|
||||
* accepts a single LLSD value, presumably containing other parameters.
|
||||
*/
|
||||
template <class CLASS>
|
||||
void add(const std::string& name,
|
||||
|
|
@ -81,7 +139,8 @@ public:
|
|||
addMethod<CLASS>(name, desc, method, required);
|
||||
}
|
||||
|
||||
/// Overload for both const and non-const methods
|
||||
/// Overload for both const and non-const methods. The passed @a method
|
||||
/// accepts a single LLSD value, presumably containing other parameters.
|
||||
template <class CLASS>
|
||||
void add(const std::string& name,
|
||||
const std::string& desc,
|
||||
|
|
@ -91,15 +150,106 @@ public:
|
|||
addMethod<CLASS>(name, desc, method, required);
|
||||
}
|
||||
|
||||
/// Convenience: for LLEventDispatcher, not every callable needs a
|
||||
/// documentation string.
|
||||
template <typename CALLABLE>
|
||||
void add(const std::string& name,
|
||||
CALLABLE callable,
|
||||
const LLSD& required=LLSD())
|
||||
{
|
||||
add(name, "", callable, required);
|
||||
}
|
||||
//@}
|
||||
|
||||
/// @name Register functions with arbitrary param lists
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Register a free function with arbitrary parameters. (This also works
|
||||
* for static class methods.)
|
||||
*
|
||||
* @note This supports functions with up to about 6 parameters -- after
|
||||
* that you start getting dismaying compile errors in which
|
||||
* boost::fusion::joint_view is mentioned a surprising number of times.
|
||||
*
|
||||
* When calling this name, pass an LLSD::Array. Each entry in turn will be
|
||||
* converted to the corresponding parameter type using LLSDParam.
|
||||
*/
|
||||
template<typename Function>
|
||||
typename boost::enable_if< boost::function_types::is_nonmember_callable_builtin<Function>
|
||||
>::type add(const std::string& name,
|
||||
const std::string& desc,
|
||||
Function f);
|
||||
|
||||
/**
|
||||
* Register a nonstatic class method with arbitrary parameters.
|
||||
*
|
||||
* @note This supports functions with up to about 6 parameters -- after
|
||||
* that you start getting dismaying compile errors in which
|
||||
* boost::fusion::joint_view is mentioned a surprising number of times.
|
||||
*
|
||||
* To cover cases such as a method on an LLSingleton we don't yet want to
|
||||
* instantiate, instead of directly storing an instance pointer, accept a
|
||||
* nullary callable returning a pointer/reference to the desired class
|
||||
* instance. If you already have an instance in hand,
|
||||
* boost::lambda::var(instance) or boost::lambda::constant(instance_ptr)
|
||||
* produce suitable callables.
|
||||
*
|
||||
* When calling this name, pass an LLSD::Array. Each entry in turn will be
|
||||
* converted to the corresponding parameter type using LLSDParam.
|
||||
*/
|
||||
template<typename Method, typename InstanceGetter>
|
||||
typename boost::enable_if< boost::function_types::is_member_function_pointer<Method>
|
||||
>::type add(const std::string& name,
|
||||
const std::string& desc,
|
||||
Method f,
|
||||
const InstanceGetter& getter);
|
||||
|
||||
/**
|
||||
* Register a free function with arbitrary parameters. (This also works
|
||||
* for static class methods.)
|
||||
*
|
||||
* @note This supports functions with up to about 6 parameters -- after
|
||||
* that you start getting dismaying compile errors in which
|
||||
* boost::fusion::joint_view is mentioned a surprising number of times.
|
||||
*
|
||||
* Pass an LLSD::Array of parameter names, and optionally another
|
||||
* LLSD::Array of default parameter values, a la LLSDArgsMapper.
|
||||
*
|
||||
* When calling this name, pass an LLSD::Map. We will internally generate
|
||||
* an LLSD::Array using LLSDArgsMapper and then convert each entry in turn
|
||||
* to the corresponding parameter type using LLSDParam.
|
||||
*/
|
||||
template<typename Function>
|
||||
typename boost::enable_if< boost::function_types::is_nonmember_callable_builtin<Function>
|
||||
>::type add(const std::string& name,
|
||||
const std::string& desc,
|
||||
Function f,
|
||||
const LLSD& params,
|
||||
const LLSD& defaults=LLSD());
|
||||
|
||||
/**
|
||||
* Register a nonstatic class method with arbitrary parameters.
|
||||
*
|
||||
* @note This supports functions with up to about 6 parameters -- after
|
||||
* that you start getting dismaying compile errors in which
|
||||
* boost::fusion::joint_view is mentioned a surprising number of times.
|
||||
*
|
||||
* To cover cases such as a method on an LLSingleton we don't yet want to
|
||||
* instantiate, instead of directly storing an instance pointer, accept a
|
||||
* nullary callable returning a pointer/reference to the desired class
|
||||
* instance. If you already have an instance in hand,
|
||||
* boost::lambda::var(instance) or boost::lambda::constant(instance_ptr)
|
||||
* produce suitable callables.
|
||||
*
|
||||
* Pass an LLSD::Array of parameter names, and optionally another
|
||||
* LLSD::Array of default parameter values, a la LLSDArgsMapper.
|
||||
*
|
||||
* When calling this name, pass an LLSD::Map. We will internally generate
|
||||
* an LLSD::Array using LLSDArgsMapper and then convert each entry in turn
|
||||
* to the corresponding parameter type using LLSDParam.
|
||||
*/
|
||||
template<typename Method, typename InstanceGetter>
|
||||
typename boost::enable_if< boost::function_types::is_member_function_pointer<Method>
|
||||
>::type add(const std::string& name,
|
||||
const std::string& desc,
|
||||
Method f,
|
||||
const InstanceGetter& getter,
|
||||
const LLSD& params,
|
||||
const LLSD& defaults=LLSD());
|
||||
|
||||
//@}
|
||||
|
||||
/// Unregister a callable
|
||||
bool remove(const std::string& name);
|
||||
|
|
@ -109,12 +259,25 @@ public:
|
|||
/// the @a required prototype specified at add() time, die with LL_ERRS.
|
||||
void operator()(const std::string& name, const LLSD& event) const;
|
||||
|
||||
/// Call a registered callable with an explicitly-specified name and
|
||||
/// return <tt>true</tt>. If no such callable exists, return
|
||||
/// <tt>false</tt>. If the @a event fails to match the @a required
|
||||
/// prototype specified at add() time, die with LL_ERRS.
|
||||
bool try_call(const std::string& name, const LLSD& event) const;
|
||||
|
||||
/// Extract the @a key value from the incoming @a event, and call the
|
||||
/// callable whose name is specified by that map @a key. If no such
|
||||
/// callable exists, die with LL_ERRS. If the @a event fails to match the
|
||||
/// @a required prototype specified at add() time, die with LL_ERRS.
|
||||
void operator()(const LLSD& event) const;
|
||||
|
||||
/// Extract the @a key value from the incoming @a event, call the callable
|
||||
/// whose name is specified by that map @a key and return <tt>true</tt>.
|
||||
/// If no such callable exists, return <tt>false</tt>. If the @a event
|
||||
/// fails to match the @a required prototype specified at add() time, die
|
||||
/// with LL_ERRS.
|
||||
bool try_call(const LLSD& event) const;
|
||||
|
||||
/// @name Iterate over defined names
|
||||
//@{
|
||||
typedef std::pair<std::string, std::string> NameDesc;
|
||||
|
|
@ -122,16 +285,22 @@ public:
|
|||
private:
|
||||
struct DispatchEntry
|
||||
{
|
||||
DispatchEntry(const Callable& func, const std::string& desc, const LLSD& required):
|
||||
mFunc(func),
|
||||
mDesc(desc),
|
||||
mRequired(required)
|
||||
{}
|
||||
Callable mFunc;
|
||||
DispatchEntry(const std::string& desc);
|
||||
virtual ~DispatchEntry() {} // suppress MSVC warning, sigh
|
||||
|
||||
std::string mDesc;
|
||||
LLSD mRequired;
|
||||
|
||||
virtual void call(const std::string& desc, const LLSD& event) const = 0;
|
||||
virtual LLSD addMetadata(LLSD) const = 0;
|
||||
};
|
||||
typedef std::map<std::string, DispatchEntry> DispatchMap;
|
||||
// Tried using boost::ptr_map<std::string, DispatchEntry>, but ptr_map<>
|
||||
// wants its value type to be "clonable," even just to dereference an
|
||||
// iterator. I don't want to clone entries -- if I have to copy an entry
|
||||
// around, I want it to continue pointing to the same DispatchEntry
|
||||
// subclass object. However, I definitely want DispatchMap to destroy
|
||||
// DispatchEntry if no references are outstanding at the time an entry is
|
||||
// removed. This looks like a job for boost::shared_ptr.
|
||||
typedef std::map<std::string, boost::shared_ptr<DispatchEntry> > DispatchMap;
|
||||
|
||||
public:
|
||||
/// We want the flexibility to redefine what data we store per name,
|
||||
|
|
@ -149,10 +318,6 @@ public:
|
|||
}
|
||||
//@}
|
||||
|
||||
/// Fetch the Callable for the specified name. If no such name was
|
||||
/// registered, return an empty() Callable.
|
||||
Callable get(const std::string& name) const;
|
||||
|
||||
/// Get information about a specific Callable
|
||||
LLSD getMetadata(const std::string& name) const;
|
||||
|
||||
|
|
@ -175,18 +340,184 @@ private:
|
|||
}
|
||||
}
|
||||
void addFail(const std::string& name, const std::string& classname) const;
|
||||
/// try to dispatch, return @c true if success
|
||||
bool attemptCall(const std::string& name, const LLSD& event) const;
|
||||
|
||||
std::string mDesc, mKey;
|
||||
DispatchMap mDispatch;
|
||||
|
||||
static NameDesc makeNameDesc(const DispatchMap::value_type& item)
|
||||
{
|
||||
return NameDesc(item.first, item.second.mDesc);
|
||||
return NameDesc(item.first, item.second->mDesc);
|
||||
}
|
||||
|
||||
struct LLSDDispatchEntry;
|
||||
struct ParamsDispatchEntry;
|
||||
struct ArrayParamsDispatchEntry;
|
||||
struct MapParamsDispatchEntry;
|
||||
|
||||
// Step 2 of parameter analysis. Instantiating invoker<some_function_type>
|
||||
// implicitly sets its From and To parameters to the (compile time) begin
|
||||
// and end iterators over that function's parameter types.
|
||||
template< typename Function
|
||||
, class From = typename boost::mpl::begin< boost::function_types::parameter_types<Function> >::type
|
||||
, class To = typename boost::mpl::end< boost::function_types::parameter_types<Function> >::type
|
||||
>
|
||||
struct invoker;
|
||||
|
||||
// deliver LLSD arguments one at a time
|
||||
typedef boost::function<LLSD()> args_source;
|
||||
// obtain args from an args_source to build param list and call target
|
||||
// function
|
||||
typedef boost::function<void(const args_source&)> invoker_function;
|
||||
|
||||
template <typename Function>
|
||||
invoker_function make_invoker(Function f);
|
||||
template <typename Method, typename InstanceGetter>
|
||||
invoker_function make_invoker(Method f, const InstanceGetter& getter);
|
||||
void addArrayParamsDispatchEntry(const std::string& name,
|
||||
const std::string& desc,
|
||||
const invoker_function& invoker,
|
||||
LLSD::Integer arity);
|
||||
void addMapParamsDispatchEntry(const std::string& name,
|
||||
const std::string& desc,
|
||||
const invoker_function& invoker,
|
||||
const LLSD& params,
|
||||
const LLSD& defaults);
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LLEventDispatcher template implementation details
|
||||
*****************************************************************************/
|
||||
// Step 3 of parameter analysis, the recursive case.
|
||||
template<typename Function, class From, class To>
|
||||
struct LLEventDispatcher::invoker
|
||||
{
|
||||
template<typename T>
|
||||
struct remove_cv_ref
|
||||
: boost::remove_cv< typename boost::remove_reference<T>::type >
|
||||
{ };
|
||||
|
||||
// apply() accepts an arbitrary boost::fusion sequence as args. It
|
||||
// examines the next parameter type in the parameter-types sequence
|
||||
// bounded by From and To, obtains the next LLSD object from the passed
|
||||
// args_source and constructs an LLSDParam of appropriate type to try
|
||||
// to convert the value. It then recurs with the next parameter-types
|
||||
// iterator, passing the args sequence thus far.
|
||||
template<typename Args>
|
||||
static inline
|
||||
void apply(Function func, const args_source& argsrc, Args const & args)
|
||||
{
|
||||
typedef typename boost::mpl::deref<From>::type arg_type;
|
||||
typedef typename boost::mpl::next<From>::type next_iter_type;
|
||||
typedef typename remove_cv_ref<arg_type>::type plain_arg_type;
|
||||
|
||||
invoker<Function, next_iter_type, To>::apply
|
||||
( func, argsrc, boost::fusion::push_back(args, LLSDParam<plain_arg_type>(argsrc())));
|
||||
}
|
||||
|
||||
// Special treatment for instance (first) parameter of a non-static member
|
||||
// function. Accept the instance-getter callable, calling that to produce
|
||||
// the first args value. Since we know we're at the top of the recursion
|
||||
// chain, we need not also require a partial args sequence from our caller.
|
||||
template <typename InstanceGetter>
|
||||
static inline
|
||||
void method_apply(Function func, const args_source& argsrc, const InstanceGetter& getter)
|
||||
{
|
||||
typedef typename boost::mpl::next<From>::type next_iter_type;
|
||||
|
||||
// Instead of grabbing the first item from argsrc and making an
|
||||
// LLSDParam of it, call getter() and pass that as the instance param.
|
||||
invoker<Function, next_iter_type, To>::apply
|
||||
( func, argsrc, boost::fusion::push_back(boost::fusion::nil(), boost::ref(getter())));
|
||||
}
|
||||
};
|
||||
|
||||
// Step 4 of parameter analysis, the leaf case. When the general
|
||||
// invoker<Function, From, To> logic has advanced From until it matches To,
|
||||
// the compiler will pick this template specialization.
|
||||
template<typename Function, class To>
|
||||
struct LLEventDispatcher::invoker<Function,To,To>
|
||||
{
|
||||
// the argument list is complete, now call the function
|
||||
template<typename Args>
|
||||
static inline
|
||||
void apply(Function func, const args_source&, Args const & args)
|
||||
{
|
||||
boost::fusion::invoke(func, args);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Function>
|
||||
typename boost::enable_if< boost::function_types::is_nonmember_callable_builtin<Function> >::type
|
||||
LLEventDispatcher::add(const std::string& name, const std::string& desc, Function f)
|
||||
{
|
||||
// Construct an invoker_function, a callable accepting const args_source&.
|
||||
// Add to DispatchMap an ArrayParamsDispatchEntry that will handle the
|
||||
// caller's LLSD::Array.
|
||||
addArrayParamsDispatchEntry(name, desc, make_invoker(f),
|
||||
boost::function_types::function_arity<Function>::value);
|
||||
}
|
||||
|
||||
template<typename Method, typename InstanceGetter>
|
||||
typename boost::enable_if< boost::function_types::is_member_function_pointer<Method> >::type
|
||||
LLEventDispatcher::add(const std::string& name, const std::string& desc, Method f,
|
||||
const InstanceGetter& getter)
|
||||
{
|
||||
// Subtract 1 from the compile-time arity because the getter takes care of
|
||||
// the first parameter. We only need (arity - 1) additional arguments.
|
||||
addArrayParamsDispatchEntry(name, desc, make_invoker(f, getter),
|
||||
boost::function_types::function_arity<Method>::value - 1);
|
||||
}
|
||||
|
||||
template<typename Function>
|
||||
typename boost::enable_if< boost::function_types::is_nonmember_callable_builtin<Function> >::type
|
||||
LLEventDispatcher::add(const std::string& name, const std::string& desc, Function f,
|
||||
const LLSD& params, const LLSD& defaults)
|
||||
{
|
||||
// See comments for previous is_nonmember_callable_builtin add().
|
||||
addMapParamsDispatchEntry(name, desc, make_invoker(f), params, defaults);
|
||||
}
|
||||
|
||||
template<typename Method, typename InstanceGetter>
|
||||
typename boost::enable_if< boost::function_types::is_member_function_pointer<Method> >::type
|
||||
LLEventDispatcher::add(const std::string& name, const std::string& desc, Method f,
|
||||
const InstanceGetter& getter,
|
||||
const LLSD& params, const LLSD& defaults)
|
||||
{
|
||||
addMapParamsDispatchEntry(name, desc, make_invoker(f, getter), params, defaults);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
LLEventDispatcher::invoker_function
|
||||
LLEventDispatcher::make_invoker(Function f)
|
||||
{
|
||||
// Step 1 of parameter analysis, the top of the recursion. Passing a
|
||||
// suitable f (see add()'s enable_if condition) to this method causes it
|
||||
// to infer the function type; specifying that function type to invoker<>
|
||||
// causes it to fill in the begin/end MPL iterators over the function's
|
||||
// list of parameter types.
|
||||
// While normally invoker::apply() could infer its template type from the
|
||||
// boost::fusion::nil parameter value, here we must be explicit since
|
||||
// we're boost::bind()ing it rather than calling it directly.
|
||||
return boost::bind(&invoker<Function>::template apply<boost::fusion::nil>,
|
||||
f,
|
||||
_1,
|
||||
boost::fusion::nil());
|
||||
}
|
||||
|
||||
template <typename Method, typename InstanceGetter>
|
||||
LLEventDispatcher::invoker_function
|
||||
LLEventDispatcher::make_invoker(Method f, const InstanceGetter& getter)
|
||||
{
|
||||
// Use invoker::method_apply() to treat the instance (first) arg specially.
|
||||
return boost::bind(&invoker<Method>::template method_apply<InstanceGetter>,
|
||||
f,
|
||||
_1,
|
||||
getter);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* LLDispatchListener
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* Bundle an LLEventPump and a listener with an LLEventDispatcher. A class
|
||||
* that contains (or derives from) LLDispatchListener need only specify the
|
||||
|
|
|
|||
|
|
@ -588,3 +588,16 @@ void LLReqID::stamp(LLSD& response) const
|
|||
}
|
||||
response["reqid"] = mReqid;
|
||||
}
|
||||
|
||||
bool sendReply(const LLSD& reply, const LLSD& request, const std::string& replyKey)
|
||||
{
|
||||
// Copy 'reply' to modify it.
|
||||
LLSD newreply(reply);
|
||||
// Get the ["reqid"] element from request
|
||||
LLReqID reqID(request);
|
||||
// and copy it to 'newreply'.
|
||||
reqID.stamp(newreply);
|
||||
// Send reply on LLEventPump named in request[replyKey]. Don't forget to
|
||||
// send the modified 'newreply' instead of the original 'reply'.
|
||||
return LLEventPumps::instance().obtain(request[replyKey]).post(newreply);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -691,6 +691,20 @@ private:
|
|||
LLSD mReqid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Conventionally send a reply to a request event.
|
||||
*
|
||||
* @a reply is the LLSD reply event to send
|
||||
* @a request is the corresponding LLSD request event
|
||||
* @a replyKey is the key in the @a request event, conventionally ["reply"],
|
||||
* whose value is the name of the LLEventPump on which to send the reply.
|
||||
*
|
||||
* Before sending the reply event, sendReply() copies the ["reqid"] item from
|
||||
* the request to the reply.
|
||||
*/
|
||||
LL_COMMON_API bool sendReply(const LLSD& reply, const LLSD& request,
|
||||
const std::string& replyKey="reply");
|
||||
|
||||
/**
|
||||
* Base class for LLListenerWrapper. See visit_and_connect() and llwrap(). We
|
||||
* provide virtual @c accept_xxx() methods, customization points allowing a
|
||||
|
|
|
|||
|
|
@ -32,6 +32,17 @@
|
|||
// external library headers
|
||||
// other Linden headers
|
||||
|
||||
// llinstancetracker.h is presently header-only. This file exists only because our CMake
|
||||
// test macro ADD_BUILD_TEST requires it.
|
||||
int dummy = 0;
|
||||
//static
|
||||
void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
|
||||
{
|
||||
static std::map<std::string, void *> instances;
|
||||
|
||||
std::string k = info.name();
|
||||
if(instances.find(k) == instances.end())
|
||||
{
|
||||
instances[k] = NULL;
|
||||
}
|
||||
|
||||
return instances[k];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,14 +37,21 @@
|
|||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/iterator/indirect_iterator.hpp>
|
||||
|
||||
class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
|
||||
{
|
||||
protected:
|
||||
static void * & getInstances(std::type_info const & info);
|
||||
};
|
||||
|
||||
/// This mix-in class adds support for tracking all instances of the specified class parameter T
|
||||
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
|
||||
/// If KEY is not provided, then instances are stored in a simple set
|
||||
/// @NOTE: see explicit specialization below for default KEY==T* case
|
||||
template<typename T, typename KEY = T*>
|
||||
class LLInstanceTracker : boost::noncopyable
|
||||
class LLInstanceTracker : public LLInstanceTrackerBase
|
||||
{
|
||||
typedef typename std::map<KEY, T*> InstanceMap;
|
||||
typedef LLInstanceTracker<T, KEY> MyT;
|
||||
typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter;
|
||||
typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter;
|
||||
public:
|
||||
|
|
@ -99,25 +106,26 @@ private:
|
|||
|
||||
static InstanceMap& getMap_()
|
||||
{
|
||||
if (! sInstances)
|
||||
void * & instances = getInstances(typeid(MyT));
|
||||
if (! instances)
|
||||
{
|
||||
sInstances = new InstanceMap;
|
||||
instances = new InstanceMap;
|
||||
}
|
||||
return *sInstances;
|
||||
return * static_cast<InstanceMap*>(instances);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
KEY mKey;
|
||||
static InstanceMap* sInstances;
|
||||
};
|
||||
|
||||
/// explicit specialization for default case where KEY is T*
|
||||
/// use a simple std::set<T*>
|
||||
template<typename T>
|
||||
class LLInstanceTracker<T, T*>
|
||||
class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
|
||||
{
|
||||
typedef typename std::set<T*> InstanceSet;
|
||||
typedef LLInstanceTracker<T, T*> MyT;
|
||||
public:
|
||||
/// Dereferencing key_iter gives you a T* (since T* is the key)
|
||||
typedef typename InstanceSet::iterator key_iter;
|
||||
|
|
@ -172,19 +180,17 @@ protected:
|
|||
|
||||
static InstanceSet& getSet_()
|
||||
{
|
||||
if (! sInstances)
|
||||
void * & instances = getInstances(typeid(MyT));
|
||||
if (! instances)
|
||||
{
|
||||
sInstances = new InstanceSet;
|
||||
instances = new InstanceSet;
|
||||
}
|
||||
return *sInstances;
|
||||
return * static_cast<InstanceSet *>(instances);
|
||||
}
|
||||
|
||||
static InstanceSet* sInstances;
|
||||
static S32 sIterationNestDepth;
|
||||
};
|
||||
|
||||
template <typename T, typename KEY> typename LLInstanceTracker<T, KEY>::InstanceMap* LLInstanceTracker<T, KEY>::sInstances = NULL;
|
||||
template <typename T> typename LLInstanceTracker<T, T*>::InstanceSet* LLInstanceTracker<T, T*>::sInstances = NULL;
|
||||
template <typename T> S32 LLInstanceTracker<T, T*>::sIterationNestDepth = 0;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -63,7 +63,18 @@ BOOL LLMetricPerformanceTesterBasic::addTester(LLMetricPerformanceTesterBasic* t
|
|||
sTesterMap.insert(std::make_pair(name, tester));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*static*/
|
||||
void LLMetricPerformanceTesterBasic::deleteTester(std::string name)
|
||||
{
|
||||
name_tester_map_t::iterator tester = sTesterMap.find(name);
|
||||
if (tester != sTesterMap.end())
|
||||
{
|
||||
delete tester->second;
|
||||
sTesterMap.erase(tester);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name)
|
||||
{
|
||||
|
|
@ -83,7 +94,78 @@ BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name)
|
|||
return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME)));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& is)
|
||||
{
|
||||
LLSD ret;
|
||||
LLSD cur;
|
||||
|
||||
while (!is.eof() && LLSDSerialize::fromXML(cur, is))
|
||||
{
|
||||
for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
|
||||
{
|
||||
std::string label = iter->first;
|
||||
|
||||
LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ;
|
||||
if(tester)
|
||||
{
|
||||
ret[label]["Name"] = iter->second["Name"] ;
|
||||
|
||||
S32 num_of_metrics = tester->getNumberOfMetrics() ;
|
||||
for(S32 index = 0 ; index < num_of_metrics ; index++)
|
||||
{
|
||||
ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLMetricPerformanceTesterBasic::doAnalysisMetrics(std::string baseline, std::string target, std::string output)
|
||||
{
|
||||
if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
// Open baseline and current target, exit if one is inexistent
|
||||
std::ifstream base_is(baseline.c_str());
|
||||
std::ifstream target_is(target.c_str());
|
||||
if (!base_is.is_open() || !target_is.is_open())
|
||||
{
|
||||
llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl;
|
||||
base_is.close();
|
||||
target_is.close();
|
||||
return;
|
||||
}
|
||||
|
||||
//analyze baseline
|
||||
LLSD base = analyzeMetricPerformanceLog(base_is);
|
||||
base_is.close();
|
||||
|
||||
//analyze current
|
||||
LLSD current = analyzeMetricPerformanceLog(target_is);
|
||||
target_is.close();
|
||||
|
||||
//output comparision
|
||||
std::ofstream os(output.c_str());
|
||||
|
||||
os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";
|
||||
for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ;
|
||||
iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter)
|
||||
{
|
||||
LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;
|
||||
tester->analyzePerformance(&os, &base, ¤t) ;
|
||||
}
|
||||
|
||||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// LLMetricPerformanceTesterBasic : Tester instance methods
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public:
|
|||
*/
|
||||
virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ;
|
||||
|
||||
static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ;
|
||||
|
||||
/**
|
||||
* @return Returns the number of the test metrics in this tester instance.
|
||||
*/
|
||||
|
|
@ -116,6 +118,7 @@ protected:
|
|||
private:
|
||||
void preOutputTestResults(LLSD* sd) ;
|
||||
void postOutputTestResults(LLSD* sd) ;
|
||||
static LLSD analyzeMetricPerformanceLog(std::istream& is) ;
|
||||
|
||||
std::string mName ; // Name of this tester instance
|
||||
S32 mCount ; // Current record count
|
||||
|
|
@ -134,6 +137,12 @@ public:
|
|||
*/
|
||||
static LLMetricPerformanceTesterBasic* getTester(std::string name) ;
|
||||
|
||||
/**
|
||||
* @return Delete the named tester from the list
|
||||
* @param[in] name - Name of the tester instance to delete.
|
||||
*/
|
||||
static void deleteTester(std::string name);
|
||||
|
||||
/**
|
||||
* @return Returns TRUE if that metric *or* the default catch all metric has been requested to be logged
|
||||
* @param[in] name - Name of the tester queried.
|
||||
|
|
|
|||
|
|
@ -103,10 +103,30 @@ int LLProcessLauncher::launch(void)
|
|||
char *args2 = new char[args.size() + 1];
|
||||
strcpy(args2, args.c_str());
|
||||
|
||||
if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, mWorkingDir.c_str(), &sinfo, &pinfo ) )
|
||||
const char * working_directory = 0;
|
||||
if(!mWorkingDir.empty()) working_directory = mWorkingDir.c_str();
|
||||
if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, working_directory, &sinfo, &pinfo ) )
|
||||
{
|
||||
// TODO: do better than returning the OS-specific error code on failure...
|
||||
result = GetLastError();
|
||||
|
||||
LPTSTR error_str = 0;
|
||||
if(
|
||||
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
result,
|
||||
0,
|
||||
(LPTSTR)&error_str,
|
||||
0,
|
||||
NULL)
|
||||
!= 0)
|
||||
{
|
||||
char message[256];
|
||||
wcstombs(message, error_str, 256);
|
||||
message[255] = 0;
|
||||
llwarns << "CreateProcessA failed: " << message << llendl;
|
||||
LocalFree(error_str);
|
||||
}
|
||||
|
||||
if(result == 0)
|
||||
{
|
||||
// Make absolutely certain we return a non-zero value on failure.
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "llsdserialize.h"
|
||||
#include "stringize.h"
|
||||
#include "is_approx_equal_fraction.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
|
@ -571,7 +572,7 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str
|
|||
return match_types(prototype.type(), TypeVector(), data.type(), pfx);
|
||||
}
|
||||
|
||||
bool llsd_equals(const LLSD& lhs, const LLSD& rhs)
|
||||
bool llsd_equals(const LLSD& lhs, const LLSD& rhs, unsigned bits)
|
||||
{
|
||||
// We're comparing strict equality of LLSD representation rather than
|
||||
// performing any conversions. So if the types aren't equal, the LLSD
|
||||
|
|
@ -588,6 +589,20 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs)
|
|||
// Both are TypeUndefined. There's nothing more to know.
|
||||
return true;
|
||||
|
||||
case LLSD::TypeReal:
|
||||
// This is where the 'bits' argument comes in handy. If passed
|
||||
// explicitly, it means to use is_approx_equal_fraction() to compare.
|
||||
if (bits >= 0)
|
||||
{
|
||||
return is_approx_equal_fraction(lhs.asReal(), rhs.asReal(), bits);
|
||||
}
|
||||
// Otherwise we compare bit representations, and the usual caveats
|
||||
// about comparing floating-point numbers apply. Omitting 'bits' when
|
||||
// comparing Real values is only useful when we expect identical bit
|
||||
// representation for a given Real value, e.g. for integer-valued
|
||||
// Reals.
|
||||
return (lhs.asReal() == rhs.asReal());
|
||||
|
||||
#define COMPARE_SCALAR(type) \
|
||||
case LLSD::Type##type: \
|
||||
/* LLSD::URI has operator!=() but not operator==() */ \
|
||||
|
|
@ -596,10 +611,6 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs)
|
|||
|
||||
COMPARE_SCALAR(Boolean);
|
||||
COMPARE_SCALAR(Integer);
|
||||
// The usual caveats about comparing floating-point numbers apply. This is
|
||||
// only useful when we expect identical bit representation for a given
|
||||
// Real value, e.g. for integer-valued Reals.
|
||||
COMPARE_SCALAR(Real);
|
||||
COMPARE_SCALAR(String);
|
||||
COMPARE_SCALAR(UUID);
|
||||
COMPARE_SCALAR(Date);
|
||||
|
|
@ -617,7 +628,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs)
|
|||
for ( ; lai != laend && rai != raend; ++lai, ++rai)
|
||||
{
|
||||
// If any one array element is unequal, the arrays are unequal.
|
||||
if (! llsd_equals(*lai, *rai))
|
||||
if (! llsd_equals(*lai, *rai, bits))
|
||||
return false;
|
||||
}
|
||||
// Here we've reached the end of one or the other array. They're equal
|
||||
|
|
@ -644,7 +655,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs)
|
|||
if (rhskeys.erase(lmi->first) != 1)
|
||||
return false;
|
||||
// Both maps have the current key. Compare values.
|
||||
if (! llsd_equals(lmi->second, rhs[lmi->first]))
|
||||
if (! llsd_equals(lmi->second, rhs[lmi->first], bits))
|
||||
return false;
|
||||
}
|
||||
// We've now established that all the lhs keys have equal values in
|
||||
|
|
@ -657,7 +668,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs)
|
|||
// We expect that every possible type() value is specifically handled
|
||||
// above. Failing to extend this switch to support a new LLSD type is
|
||||
// an error that must be brought to the coder's attention.
|
||||
LL_ERRS("llsd_equals") << "llsd_equals(" << lhs << ", " << rhs << "): "
|
||||
LL_ERRS("llsd_equals") << "llsd_equals(" << lhs << ", " << rhs << ", " << bits << "): "
|
||||
"unknown type " << lhs.type() << LL_ENDL;
|
||||
return false; // pacify the compiler
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,8 +123,10 @@ LL_COMMON_API BOOL compare_llsd_with_template(
|
|||
*/
|
||||
LL_COMMON_API std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::string& pfx="");
|
||||
|
||||
/// Deep equality
|
||||
LL_COMMON_API bool llsd_equals(const LLSD& lhs, const LLSD& rhs);
|
||||
/// Deep equality. If you want to compare LLSD::Real values for approximate
|
||||
/// equality rather than bitwise equality, pass @a bits as for
|
||||
/// is_approx_equal_fraction().
|
||||
LL_COMMON_API bool llsd_equals(const LLSD& lhs, const LLSD& rhs, unsigned bits=-1);
|
||||
|
||||
// Simple function to copy data out of input & output iterators if
|
||||
// there is no need for casting.
|
||||
|
|
@ -138,4 +140,283 @@ template<typename Input> LLSD llsd_copy_array(Input iter, Input end)
|
|||
return dest;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* LLSDArray
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* Construct an LLSD::Array inline, with implicit conversion to LLSD. Usage:
|
||||
*
|
||||
* @code
|
||||
* void somefunc(const LLSD&);
|
||||
* ...
|
||||
* somefunc(LLSDArray("text")(17)(3.14));
|
||||
* @endcode
|
||||
*
|
||||
* For completeness, LLSDArray() with no args constructs an empty array, so
|
||||
* <tt>LLSDArray()("text")(17)(3.14)</tt> produces an array equivalent to the
|
||||
* above. But for most purposes, LLSD() is already equivalent to an empty
|
||||
* array, and if you explicitly want an empty isArray(), there's
|
||||
* LLSD::emptyArray(). However, supporting a no-args LLSDArray() constructor
|
||||
* follows the principle of least astonishment.
|
||||
*/
|
||||
class LLSDArray
|
||||
{
|
||||
public:
|
||||
LLSDArray():
|
||||
_data(LLSD::emptyArray())
|
||||
{}
|
||||
|
||||
/**
|
||||
* Need an explicit copy constructor. Consider the following:
|
||||
*
|
||||
* @code
|
||||
* LLSD array_of_arrays(LLSDArray(LLSDArray(17)(34))
|
||||
* (LLSDArray("x")("y")));
|
||||
* @endcode
|
||||
*
|
||||
* The coder intends to construct [[17, 34], ["x", "y"]].
|
||||
*
|
||||
* With the compiler's implicit copy constructor, s/he gets instead
|
||||
* [17, 34, ["x", "y"]].
|
||||
*
|
||||
* The expression LLSDArray(17)(34) constructs an LLSDArray with those two
|
||||
* values. The reader assumes it should be converted to LLSD, as we always
|
||||
* want with LLSDArray, before passing it to the @em outer LLSDArray
|
||||
* constructor! This copy constructor makes that happen.
|
||||
*/
|
||||
LLSDArray(const LLSDArray& inner):
|
||||
_data(LLSD::emptyArray())
|
||||
{
|
||||
_data.append(inner);
|
||||
}
|
||||
|
||||
LLSDArray(const LLSD& value):
|
||||
_data(LLSD::emptyArray())
|
||||
{
|
||||
_data.append(value);
|
||||
}
|
||||
|
||||
LLSDArray& operator()(const LLSD& value)
|
||||
{
|
||||
_data.append(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator LLSD() const { return _data; }
|
||||
LLSD get() const { return _data; }
|
||||
|
||||
private:
|
||||
LLSD _data;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LLSDMap
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* Construct an LLSD::Map inline, with implicit conversion to LLSD. Usage:
|
||||
*
|
||||
* @code
|
||||
* void somefunc(const LLSD&);
|
||||
* ...
|
||||
* somefunc(LLSDMap("alpha", "abc")("number", 17)("pi", 3.14));
|
||||
* @endcode
|
||||
*
|
||||
* For completeness, LLSDMap() with no args constructs an empty map, so
|
||||
* <tt>LLSDMap()("alpha", "abc")("number", 17)("pi", 3.14)</tt> produces a map
|
||||
* equivalent to the above. But for most purposes, LLSD() is already
|
||||
* equivalent to an empty map, and if you explicitly want an empty isMap(),
|
||||
* there's LLSD::emptyMap(). However, supporting a no-args LLSDMap()
|
||||
* constructor follows the principle of least astonishment.
|
||||
*/
|
||||
class LLSDMap
|
||||
{
|
||||
public:
|
||||
LLSDMap():
|
||||
_data(LLSD::emptyMap())
|
||||
{}
|
||||
LLSDMap(const LLSD::String& key, const LLSD& value):
|
||||
_data(LLSD::emptyMap())
|
||||
{
|
||||
_data[key] = value;
|
||||
}
|
||||
|
||||
LLSDMap& operator()(const LLSD::String& key, const LLSD& value)
|
||||
{
|
||||
_data[key] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator LLSD() const { return _data; }
|
||||
LLSD get() const { return _data; }
|
||||
|
||||
private:
|
||||
LLSD _data;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LLSDParam
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* LLSDParam is a customization point for passing LLSD values to function
|
||||
* parameters of more or less arbitrary type. LLSD provides a small set of
|
||||
* native conversions; but if a generic algorithm explicitly constructs an
|
||||
* LLSDParam object in the function's argument list, a consumer can provide
|
||||
* LLSDParam specializations to support more different parameter types than
|
||||
* LLSD's native conversions.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* @code
|
||||
* void somefunc(const paramtype&);
|
||||
* ...
|
||||
* somefunc(..., LLSDParam<paramtype>(someLLSD), ...);
|
||||
* @endcode
|
||||
*/
|
||||
template <typename T>
|
||||
class LLSDParam
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default implementation converts to T on construction, saves converted
|
||||
* value for later retrieval
|
||||
*/
|
||||
LLSDParam(const LLSD& value):
|
||||
_value(value)
|
||||
{}
|
||||
|
||||
operator T() const { return _value; }
|
||||
|
||||
private:
|
||||
T _value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Turns out that several target types could accept an LLSD param using any of
|
||||
* a few different conversions, e.g. LLUUID's constructor can accept LLUUID or
|
||||
* std::string. Therefore, the compiler can't decide which LLSD conversion
|
||||
* operator to choose, even though to us it seems obvious. But that's okay, we
|
||||
* can specialize LLSDParam for such target types, explicitly specifying the
|
||||
* desired conversion -- that's part of what LLSDParam is all about. Turns out
|
||||
* we have to do that enough to make it worthwhile generalizing. Use a macro
|
||||
* because I need to specify one of the asReal, etc., explicit conversion
|
||||
* methods as well as a type. If I'm overlooking a clever way to implement
|
||||
* that using a template instead, feel free to reimplement.
|
||||
*/
|
||||
#define LLSDParam_for(T, AS) \
|
||||
template <> \
|
||||
class LLSDParam<T> \
|
||||
{ \
|
||||
public: \
|
||||
LLSDParam(const LLSD& value): \
|
||||
_value(value.AS()) \
|
||||
{} \
|
||||
\
|
||||
operator T() const { return _value; } \
|
||||
\
|
||||
private: \
|
||||
T _value; \
|
||||
}
|
||||
|
||||
LLSDParam_for(float, asReal);
|
||||
LLSDParam_for(LLUUID, asUUID);
|
||||
LLSDParam_for(LLDate, asDate);
|
||||
LLSDParam_for(LLURI, asURI);
|
||||
LLSDParam_for(LLSD::Binary, asBinary);
|
||||
|
||||
/**
|
||||
* LLSDParam<const char*> is an example of the kind of conversion you can
|
||||
* support with LLSDParam beyond native LLSD conversions. Normally you can't
|
||||
* pass an LLSD object to a function accepting const char* -- but you can
|
||||
* safely pass an LLSDParam<const char*>(yourLLSD).
|
||||
*/
|
||||
template <>
|
||||
class LLSDParam<const char*>
|
||||
{
|
||||
private:
|
||||
// The difference here is that we store a std::string rather than a const
|
||||
// char*. It's important that the LLSDParam object own the std::string.
|
||||
std::string _value;
|
||||
// We don't bother storing the incoming LLSD object, but we do have to
|
||||
// distinguish whether _value is an empty string because the LLSD object
|
||||
// contains an empty string or because it's isUndefined().
|
||||
bool _undefined;
|
||||
|
||||
public:
|
||||
LLSDParam(const LLSD& value):
|
||||
_value(value),
|
||||
_undefined(value.isUndefined())
|
||||
{}
|
||||
|
||||
// The const char* we retrieve is for storage owned by our _value member.
|
||||
// That's how we guarantee that the const char* is valid for the lifetime
|
||||
// of this LLSDParam object. Constructing your LLSDParam in the argument
|
||||
// list should ensure that the LLSDParam object will persist for the
|
||||
// duration of the function call.
|
||||
operator const char*() const
|
||||
{
|
||||
if (_undefined)
|
||||
{
|
||||
// By default, an isUndefined() LLSD object's asString() method
|
||||
// will produce an empty string. But for a function accepting
|
||||
// const char*, it's often important to be able to pass NULL, and
|
||||
// isUndefined() seems like the best way. If you want to pass an
|
||||
// empty string, you can still pass LLSD(""). Without this special
|
||||
// case, though, no LLSD value could pass NULL.
|
||||
return NULL;
|
||||
}
|
||||
return _value.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
namespace llsd
|
||||
{
|
||||
|
||||
/*****************************************************************************
|
||||
* BOOST_FOREACH() helpers for LLSD
|
||||
*****************************************************************************/
|
||||
/// Usage: BOOST_FOREACH(LLSD item, inArray(someLLSDarray)) { ... }
|
||||
class inArray
|
||||
{
|
||||
public:
|
||||
inArray(const LLSD& array):
|
||||
_array(array)
|
||||
{}
|
||||
|
||||
typedef LLSD::array_const_iterator const_iterator;
|
||||
typedef LLSD::array_iterator iterator;
|
||||
|
||||
iterator begin() { return _array.beginArray(); }
|
||||
iterator end() { return _array.endArray(); }
|
||||
const_iterator begin() const { return _array.beginArray(); }
|
||||
const_iterator end() const { return _array.endArray(); }
|
||||
|
||||
private:
|
||||
LLSD _array;
|
||||
};
|
||||
|
||||
/// MapEntry is what you get from dereferencing an LLSD::map_[const_]iterator.
|
||||
typedef std::map<LLSD::String, LLSD>::value_type MapEntry;
|
||||
|
||||
/// Usage: BOOST_FOREACH([const] MapEntry& e, inMap(someLLSDmap)) { ... }
|
||||
class inMap
|
||||
{
|
||||
public:
|
||||
inMap(const LLSD& map):
|
||||
_map(map)
|
||||
{}
|
||||
|
||||
typedef LLSD::map_const_iterator const_iterator;
|
||||
typedef LLSD::map_iterator iterator;
|
||||
|
||||
iterator begin() { return _map.beginMap(); }
|
||||
iterator end() { return _map.endMap(); }
|
||||
const_iterator begin() const { return _map.beginMap(); }
|
||||
const_iterator end() const { return _map.endMap(); }
|
||||
|
||||
private:
|
||||
LLSD _map;
|
||||
};
|
||||
|
||||
} // namespace llsd
|
||||
|
||||
#endif // LL_LLSDUTIL_H
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
const S32 LL_VERSION_MAJOR = 2;
|
||||
const S32 LL_VERSION_MINOR = 6;
|
||||
const S32 LL_VERSION_PATCH = 1;
|
||||
const S32 LL_VERSION_PATCH = 4;
|
||||
const S32 LL_VERSION_BUILD = 0;
|
||||
|
||||
const char * const LL_CHANNEL = "Second Life Developer";
|
||||
|
|
|
|||
|
|
@ -258,10 +258,10 @@ namespace tut
|
|||
++const_iterator;
|
||||
ensure_equals(const_iterator->first, "def");
|
||||
ensure_equals(const_iterator->second, 2);
|
||||
NameIndexDeps::node_range node_range(nideps.get_node_range());
|
||||
ensure_equals(instance_from_range<std::vector<int> >(node_range), make< std::vector<int> >(list_of(1)(2)(3)));
|
||||
*node_range.begin() = 0;
|
||||
*node_range.begin() = 1;
|
||||
// NameIndexDeps::node_range node_range(nideps.get_node_range());
|
||||
// ensure_equals(instance_from_range<std::vector<int> >(node_range), make< std::vector<int> >(list_of(1)(2)(3)));
|
||||
// *node_range.begin() = 0;
|
||||
// *node_range.begin() = 1;
|
||||
NameIndexDeps::const_node_range const_node_range(const_nideps.get_node_range());
|
||||
ensure_equals(instance_from_range<std::vector<int> >(const_node_range), make< std::vector<int> >(list_of(1)(2)(3)));
|
||||
NameIndexDeps::const_key_range const_key_range(const_nideps.get_key_range());
|
||||
|
|
@ -278,8 +278,8 @@ namespace tut
|
|||
def);
|
||||
ensure_equals(instance_from_range<StringList>(const_nideps.get_after_range(const_nideps.get_range().begin())),
|
||||
def);
|
||||
ensure_equals(instance_from_range<StringList>(nideps.get_after_range(nideps.get_node_range().begin())),
|
||||
def);
|
||||
// ensure_equals(instance_from_range<StringList>(nideps.get_after_range(nideps.get_node_range().begin())),
|
||||
// def);
|
||||
ensure_equals(instance_from_range<StringList>(const_nideps.get_after_range(const_nideps.get_node_range().begin())),
|
||||
def);
|
||||
ensure_equals(instance_from_range<StringList>(nideps.get_after_range(nideps.get_key_range().begin())),
|
||||
|
|
|
|||
|
|
@ -48,7 +48,10 @@ namespace
|
|||
{
|
||||
static bool fatalWasCalled;
|
||||
void fatalCall(const std::string&) { fatalWasCalled = true; }
|
||||
}
|
||||
|
||||
namespace tut
|
||||
{
|
||||
class TestRecorder : public LLError::Recorder
|
||||
{
|
||||
public:
|
||||
|
|
@ -56,7 +59,7 @@ namespace
|
|||
~TestRecorder() { LLError::removeRecorder(this); }
|
||||
|
||||
void recordMessage(LLError::ELevel level,
|
||||
const std::string& message)
|
||||
const std::string& message)
|
||||
{
|
||||
mMessages.push_back(message);
|
||||
}
|
||||
|
|
@ -66,12 +69,12 @@ namespace
|
|||
|
||||
void setWantsTime(bool t) { mWantsTime = t; }
|
||||
bool wantsTime() { return mWantsTime; }
|
||||
|
||||
|
||||
std::string message(int n)
|
||||
{
|
||||
std::ostringstream test_name;
|
||||
test_name << "testing message " << n << ", not enough messages";
|
||||
|
||||
|
||||
tut::ensure(test_name.str(), n < countMessages());
|
||||
return mMessages[n];
|
||||
}
|
||||
|
|
@ -82,10 +85,7 @@ namespace
|
|||
|
||||
bool mWantsTime;
|
||||
};
|
||||
}
|
||||
|
||||
namespace tut
|
||||
{
|
||||
|
||||
struct ErrorTestData
|
||||
{
|
||||
TestRecorder mRecorder;
|
||||
|
|
@ -381,7 +381,7 @@ namespace
|
|||
}
|
||||
|
||||
typedef std::string (*LogFromFunction)(bool);
|
||||
void testLogName(TestRecorder& recorder, LogFromFunction f,
|
||||
void testLogName(tut::TestRecorder& recorder, LogFromFunction f,
|
||||
const std::string& class_name = "")
|
||||
{
|
||||
recorder.clearMessages();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -452,7 +452,7 @@ namespace tut
|
|||
checkRoundTrip(msg + " nested arrays", v);
|
||||
|
||||
v = LLSD::emptyMap();
|
||||
fillmap(v, 10, 6); // 10^6 maps
|
||||
fillmap(v, 10, 3); // 10^6 maps
|
||||
checkRoundTrip(msg + " many nested maps", v);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -266,13 +266,13 @@ public:
|
|||
// subclasses must return a prefered file extension (lowercase without a leading dot)
|
||||
virtual std::string getExtension() = 0;
|
||||
// calcHeaderSize() returns the maximum size of header;
|
||||
// 0 indicates we don't know have a header and have to lead the entire file
|
||||
// 0 indicates we don't have a header and have to read the entire file
|
||||
virtual S32 calcHeaderSize() { return 0; };
|
||||
// calcDataSize() returns how many bytes to read to load discard_level (including header)
|
||||
virtual S32 calcDataSize(S32 discard_level);
|
||||
// calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes
|
||||
virtual S32 calcDiscardLevelBytes(S32 bytes);
|
||||
// getRawDiscardLevel()by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
|
||||
// getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
|
||||
virtual S8 getRawDiscardLevel() { return mDiscardLevel; }
|
||||
|
||||
BOOL load(const std::string& filename);
|
||||
|
|
|
|||
|
|
@ -474,6 +474,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
|
|||
|
||||
LLImageCompressionTester::~LLImageCompressionTester()
|
||||
{
|
||||
outputTestResults();
|
||||
LLImageJ2C::sTesterp = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ include_directories(
|
|||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LLIMAGE_INCLUDE_DIRS}
|
||||
${KDU_INCLUDE_DIR}
|
||||
${LLKDU_INCLUDE_DIRS}
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
|
|
@ -49,6 +50,15 @@ if (USE_KDU)
|
|||
SET(llkdu_TEST_SOURCE_FILES
|
||||
llimagej2ckdu.cpp
|
||||
)
|
||||
SET(llkdu_test_additional_HEADER_FILES
|
||||
llimagej2ckdu.h
|
||||
llkdumem.h
|
||||
lltut.h
|
||||
)
|
||||
SET(llkdu_test_additional_INCLUDE_DIRS
|
||||
${KDU_INCLUDE_DIR}
|
||||
${LLKDU_INCLUDE_DIRS}
|
||||
)
|
||||
LL_ADD_PROJECT_UNIT_TESTS(llkdu "${llkdu_TEST_SOURCE_FILES}")
|
||||
endif (LL_TESTS)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
// Class to test
|
||||
#include "../llimagej2ckdu.h"
|
||||
#include "../llkdumem.h"
|
||||
#include "llimagej2ckdu.h"
|
||||
#include "llkdumem.h"
|
||||
// Tut header
|
||||
#include "../test/lltut.h"
|
||||
#include "lltut.h"
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Stubbing: Declarations required to link and run the class being tested
|
||||
|
|
|
|||
|
|
@ -37,6 +37,16 @@
|
|||
|
||||
#include "../test/lltut.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
// disable unreachable code warnings caused by usage of skip.
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
|
||||
#if LL_WINDOWS
|
||||
// disable unreachable code warnings caused by usage of skip.
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
|
||||
namespace tut
|
||||
{
|
||||
struct m3math_test
|
||||
|
|
@ -277,19 +287,21 @@ namespace tut
|
|||
LLVector3 llvec2(1, 2, 0);
|
||||
LLVector3 llvec3(2, 4, 2);
|
||||
|
||||
skip("This test fails depending on architecture. Need to fix comparison operation, is_approx_equal, to work on more than one platform.");
|
||||
|
||||
llmat_obj.setRows(llvec1, llvec2, llvec3);
|
||||
llmat_obj.orthogonalize();
|
||||
|
||||
ensure("LLMatrix3::orthogonalize failed ",
|
||||
is_approx_equal(0.19611613f, llmat_obj.mMatrix[0][0]) &&
|
||||
is_approx_equal(0.19611614f, llmat_obj.mMatrix[0][0]) &&
|
||||
is_approx_equal(0.78446454f, llmat_obj.mMatrix[0][1]) &&
|
||||
is_approx_equal(0.58834839f, llmat_obj.mMatrix[0][2]) &&
|
||||
is_approx_equal(0.47628206f, llmat_obj.mMatrix[1][0]) &&
|
||||
is_approx_equal(0.44826555f, llmat_obj.mMatrix[1][1]) &&
|
||||
is_approx_equal(-0.75644791f, llmat_obj.mMatrix[1][2]) &&
|
||||
is_approx_equal(-0.85714287f, llmat_obj.mMatrix[2][0]) &&
|
||||
is_approx_equal(0.58834841f, llmat_obj.mMatrix[0][2]) &&
|
||||
is_approx_equal(0.47628204f, llmat_obj.mMatrix[1][0]) &&
|
||||
is_approx_equal(0.44826545f, llmat_obj.mMatrix[1][1]) &&
|
||||
is_approx_equal(-0.75644795f, llmat_obj.mMatrix[1][2]) &&
|
||||
is_approx_equal(-0.85714286f, llmat_obj.mMatrix[2][0]) &&
|
||||
is_approx_equal(0.42857143f, llmat_obj.mMatrix[2][1]) &&
|
||||
is_approx_equal(-0.28571427f, llmat_obj.mMatrix[2][2]));
|
||||
is_approx_equal(-0.28571429f, llmat_obj.mMatrix[2][2]));
|
||||
}
|
||||
|
||||
//test case for adjointTranspose() fn.
|
||||
|
|
|
|||
|
|
@ -134,6 +134,21 @@ BOOL LLVector3::clampLength( F32 length_limit )
|
|||
return changed;
|
||||
}
|
||||
|
||||
BOOL LLVector3::clamp(const LLVector3 &min_vec, const LLVector3 &max_vec)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (mV[0] < min_vec[0]) { mV[0] = min_vec[0]; ret = TRUE; }
|
||||
if (mV[1] < min_vec[1]) { mV[1] = min_vec[1]; ret = TRUE; }
|
||||
if (mV[2] < min_vec[2]) { mV[2] = min_vec[2]; ret = TRUE; }
|
||||
|
||||
if (mV[0] > max_vec[0]) { mV[0] = max_vec[0]; ret = TRUE; }
|
||||
if (mV[1] > max_vec[1]) { mV[1] = max_vec[1]; ret = TRUE; }
|
||||
if (mV[2] > max_vec[2]) { mV[2] = max_vec[2]; ret = TRUE; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Sets all values to absolute value of their original values
|
||||
// Returns TRUE if data changed
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ class LLVector3
|
|||
|
||||
inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
|
||||
BOOL clamp(F32 min, F32 max); // Clamps all values to (min,max), returns TRUE if data changed
|
||||
BOOL clamp(const LLVector3 &min_vec, const LLVector3 &max_vec); // Scales vector by another vector
|
||||
BOOL clampLength( F32 length_limit ); // Scales vector to limit length to a value
|
||||
|
||||
void quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ include(LLMath)
|
|||
include(LLMessage)
|
||||
include(LLVFS)
|
||||
include(LLAddBuildTest)
|
||||
include(Python)
|
||||
include(Tut)
|
||||
include(Python)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
|
|
|||
|
|
@ -440,6 +440,9 @@ bool LLURLRequest::configure()
|
|||
case HTTP_GET:
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_HTTPGET, 1);
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
||||
// Set Accept-Encoding to allow response compression
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
|
|
@ -464,6 +467,9 @@ bool LLURLRequest::configure()
|
|||
|
||||
// Set the handle for an http post
|
||||
mDetail->mCurlRequest->setPost(NULL, bytes);
|
||||
|
||||
// Set Accept-Encoding to allow response compression
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -2441,12 +2441,12 @@ void dump_prehash_files()
|
|||
" * Generated from message template version number %.3f\n"
|
||||
" */\n",
|
||||
gMessageSystem->mMessageFileVersionNumber);
|
||||
fprintf(fp, "\n\nextern F32 gPrehashVersionNumber;\n\n");
|
||||
fprintf(fp, "\n\nextern F32 const gPrehashVersionNumber;\n\n");
|
||||
for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++)
|
||||
{
|
||||
if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.')
|
||||
{
|
||||
fprintf(fp, "extern char * _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]);
|
||||
fprintf(fp, "extern char const* const _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]);
|
||||
}
|
||||
}
|
||||
fprintf(fp, "\n\n#endif\n");
|
||||
|
|
@ -2471,12 +2471,12 @@ void dump_prehash_files()
|
|||
gMessageSystem->mMessageFileVersionNumber);
|
||||
fprintf(fp, "#include \"linden_common.h\"\n");
|
||||
fprintf(fp, "#include \"message.h\"\n\n");
|
||||
fprintf(fp, "\n\nF32 gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber);
|
||||
fprintf(fp, "\n\nF32 const gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber);
|
||||
for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++)
|
||||
{
|
||||
if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.')
|
||||
{
|
||||
fprintf(fp, "char * _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]);
|
||||
fprintf(fp, "char const* const _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -151,6 +151,7 @@ namespace tut
|
|||
template<> template<>
|
||||
void host_object::test<9>()
|
||||
{
|
||||
skip("this test is flaky, but we should figure out why...");
|
||||
// skip("setHostByName(\"google.com\"); getHostName() -> (e.g.) \"yx-in-f100.1e100.net\"");
|
||||
std::string hostStr = "lindenlab.com";
|
||||
LLHost host;
|
||||
|
|
|
|||
|
|
@ -144,8 +144,10 @@ void LLPluginClassMedia::reset()
|
|||
mStatusText.clear();
|
||||
mProgressPercent = 0;
|
||||
mClickURL.clear();
|
||||
mClickNavType.clear();
|
||||
mClickTarget.clear();
|
||||
mClickUUID.clear();
|
||||
mStatusCode = 0;
|
||||
|
||||
// media_time class
|
||||
mCurrentTime = 0.0f;
|
||||
|
|
@ -1024,9 +1026,15 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
|||
else if(message_name == "click_nofollow")
|
||||
{
|
||||
mClickURL = message.getValue("uri");
|
||||
mClickNavType = message.getValue("nav_type");
|
||||
mClickTarget.clear();
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW);
|
||||
}
|
||||
else if(message_name == "navigate_error_page")
|
||||
{
|
||||
mStatusCode = message.getValueS32("status_code");
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE);
|
||||
}
|
||||
else if(message_name == "cookie_set")
|
||||
{
|
||||
if(mOwner)
|
||||
|
|
@ -1192,16 +1200,6 @@ void LLPluginClassMedia::browse_back()
|
|||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::set_status_redirect(int code, const std::string &url)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_status_redirect");
|
||||
|
||||
message.setValueS32("code", code);
|
||||
message.setValue("url", url);
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_user_agent");
|
||||
|
|
|
|||
|
|
@ -199,7 +199,6 @@ public:
|
|||
void browse_reload(bool ignore_cache = false);
|
||||
void browse_forward();
|
||||
void browse_back();
|
||||
void set_status_redirect(int code, const std::string &url);
|
||||
void setBrowserUserAgent(const std::string& user_agent);
|
||||
void proxyWindowOpened(const std::string &target, const std::string &uuid);
|
||||
void proxyWindowClosed(const std::string &uuid);
|
||||
|
|
@ -227,11 +226,17 @@ public:
|
|||
// This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW
|
||||
std::string getClickURL() const { return mClickURL; };
|
||||
|
||||
// This is valid after MEDIA_EVENT_CLICK_LINK_NOFOLLOW
|
||||
std::string getClickNavType() const { return mClickNavType; };
|
||||
|
||||
// This is valid after MEDIA_EVENT_CLICK_LINK_HREF
|
||||
std::string getClickTarget() const { return mClickTarget; };
|
||||
|
||||
// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
|
||||
std::string getClickUUID() const { return mClickUUID; };
|
||||
|
||||
// This is valid after MEDIA_EVENT_NAVIGATE_ERROR_PAGE
|
||||
S32 getStatusCode() const { return mStatusCode; };
|
||||
|
||||
// These are valid during MEDIA_EVENT_GEOMETRY_CHANGE
|
||||
S32 getGeometryX() const { return mGeometryX; };
|
||||
|
|
@ -378,12 +383,14 @@ protected:
|
|||
int mProgressPercent;
|
||||
std::string mLocation;
|
||||
std::string mClickURL;
|
||||
std::string mClickNavType;
|
||||
std::string mClickTarget;
|
||||
std::string mClickUUID;
|
||||
S32 mGeometryX;
|
||||
S32 mGeometryY;
|
||||
S32 mGeometryWidth;
|
||||
S32 mGeometryHeight;
|
||||
S32 mStatusCode;
|
||||
std::string mAuthURL;
|
||||
std::string mAuthRealm;
|
||||
std::string mHoverText;
|
||||
|
|
|
|||
|
|
@ -52,12 +52,13 @@ public:
|
|||
MEDIA_EVENT_STATUS_TEXT_CHANGED, // browser has updated the status text
|
||||
MEDIA_EVENT_NAME_CHANGED, // browser has updated the name of the media (typically <title> tag)
|
||||
MEDIA_EVENT_LOCATION_CHANGED, // browser location (URL) has changed (maybe due to internal navagation/frames/etc)
|
||||
MEDIA_EVENT_NAVIGATE_ERROR_PAGE, // browser navigated to a page that resulted in an HTTP error
|
||||
MEDIA_EVENT_CLICK_LINK_HREF, // I'm not entirely sure what the semantics of these two are
|
||||
MEDIA_EVENT_CLICK_LINK_NOFOLLOW,
|
||||
MEDIA_EVENT_CLOSE_REQUEST, // The plugin requested its window be closed (currently hooked up to javascript window.close in webkit)
|
||||
MEDIA_EVENT_PICK_FILE_REQUEST, // The plugin wants the user to pick a file
|
||||
MEDIA_EVENT_GEOMETRY_CHANGE, // The plugin requested its window geometry be changed (per the javascript window interface)
|
||||
|
||||
|
||||
MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch
|
||||
MEDIA_EVENT_PLUGIN_FAILED, // The plugin died unexpectedly
|
||||
|
||||
|
|
|
|||
|
|
@ -1216,12 +1216,12 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name)
|
||||
S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name)
|
||||
{
|
||||
return(unpackTEMessage(mesgsys,block_name,-1));
|
||||
}
|
||||
|
||||
S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num)
|
||||
S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
|
||||
{
|
||||
// use a negative block_num to indicate a single-block read (a non-variable block)
|
||||
S32 retval = 0;
|
||||
|
|
|
|||
|
|
@ -358,8 +358,8 @@ public:
|
|||
S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type);
|
||||
BOOL packTEMessage(LLMessageSystem *mesgsys) const;
|
||||
BOOL packTEMessage(LLDataPacker &dp) const;
|
||||
S32 unpackTEMessage(LLMessageSystem *mesgsys, char *block_name);
|
||||
S32 unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num); // Variable num of blocks
|
||||
S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name);
|
||||
S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks
|
||||
BOOL unpackTEMessage(LLDataPacker &dp);
|
||||
|
||||
#ifdef CHECK_FOR_FINITE
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ bool LLVolumeMessage::packProfileParams(
|
|||
bool LLVolumeMessage::unpackProfileParams(
|
||||
LLProfileParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num)
|
||||
{
|
||||
bool ok = true;
|
||||
|
|
@ -322,7 +322,7 @@ bool LLVolumeMessage::packPathParams(
|
|||
bool LLVolumeMessage::unpackPathParams(
|
||||
LLPathParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num)
|
||||
{
|
||||
U8 curve;
|
||||
|
|
@ -522,7 +522,7 @@ bool LLVolumeMessage::packVolumeParams(const LLVolumeParams* params, LLDataPacke
|
|||
bool LLVolumeMessage::unpackVolumeParams(
|
||||
LLVolumeParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num)
|
||||
{
|
||||
bool ok = true;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ protected:
|
|||
static bool unpackProfileParams(
|
||||
LLProfileParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num = 0);
|
||||
static bool unpackProfileParams(LLProfileParams* params, LLDataPacker& dp);
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ protected:
|
|||
static bool unpackPathParams(
|
||||
LLPathParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num = 0);
|
||||
static bool unpackPathParams(LLPathParams* params, LLDataPacker& dp);
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ public:
|
|||
static bool unpackVolumeParams(
|
||||
LLVolumeParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num = 0);
|
||||
static bool unpackVolumeParams(LLVolumeParams* params, LLDataPacker &dp);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const
|
|||
if (mFTFace == NULL)
|
||||
return;
|
||||
|
||||
int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT );
|
||||
int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT );
|
||||
llassert(!error);
|
||||
|
||||
error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
|
||||
|
|
|
|||
|
|
@ -57,9 +57,12 @@
|
|||
BOOL gDebugSession = FALSE;
|
||||
BOOL gDebugGL = FALSE;
|
||||
BOOL gClothRipple = FALSE;
|
||||
BOOL gNoRender = FALSE;
|
||||
BOOL gHeadlessClient = FALSE;
|
||||
BOOL gGLActive = FALSE;
|
||||
|
||||
static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
|
||||
static const std::string HEADLESS_RENDERER_STRING("Headless");
|
||||
static const std::string HEADLESS_VERSION_STRING("1.0");
|
||||
|
||||
std::ofstream gFailLog;
|
||||
|
||||
|
|
@ -538,9 +541,19 @@ void LLGLManager::setToDebugGPU()
|
|||
|
||||
void LLGLManager::getGLInfo(LLSD& info)
|
||||
{
|
||||
info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
|
||||
info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
|
||||
info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
|
||||
if (gHeadlessClient)
|
||||
{
|
||||
info["GLInfo"]["GLVendor"] = HEADLESS_VENDOR_STRING;
|
||||
info["GLInfo"]["GLRenderer"] = HEADLESS_RENDERER_STRING;
|
||||
info["GLInfo"]["GLVersion"] = HEADLESS_VERSION_STRING;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
|
||||
info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
|
||||
info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
|
||||
}
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
std::string all_exts = ll_safe_string((const char *)gGLHExts.mSysExts);
|
||||
|
|
@ -556,14 +569,22 @@ void LLGLManager::getGLInfo(LLSD& info)
|
|||
std::string LLGLManager::getGLInfoString()
|
||||
{
|
||||
std::string info_str;
|
||||
std::string all_exts, line;
|
||||
|
||||
info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
|
||||
info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
|
||||
info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
|
||||
if (gHeadlessClient)
|
||||
{
|
||||
info_str += std::string("GL_VENDOR ") + HEADLESS_VENDOR_STRING + std::string("\n");
|
||||
info_str += std::string("GL_RENDERER ") + HEADLESS_RENDERER_STRING + std::string("\n");
|
||||
info_str += std::string("GL_VERSION ") + HEADLESS_VERSION_STRING + std::string("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
|
||||
info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
|
||||
info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
|
||||
}
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
all_exts = (const char *)gGLHExts.mSysExts;
|
||||
std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
|
||||
LLStringUtil::replaceChar(all_exts, ' ', '\n');
|
||||
info_str += std::string("GL_EXTENSIONS:\n") + all_exts + std::string("\n");
|
||||
#endif
|
||||
|
|
@ -573,15 +594,21 @@ std::string LLGLManager::getGLInfoString()
|
|||
|
||||
void LLGLManager::printGLInfoString()
|
||||
{
|
||||
std::string info_str;
|
||||
std::string all_exts, line;
|
||||
|
||||
LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
|
||||
if (gHeadlessClient)
|
||||
{
|
||||
LL_INFOS("RenderInit") << "GL_VENDOR: " << HEADLESS_VENDOR_STRING << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_RENDERER: " << HEADLESS_RENDERER_STRING << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_VERSION: " << HEADLESS_VERSION_STRING << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
|
||||
}
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
all_exts = std::string(gGLHExts.mSysExts);
|
||||
std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
|
||||
LLStringUtil::replaceChar(all_exts, ' ', '\n');
|
||||
LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
|
||||
#endif
|
||||
|
|
@ -590,7 +617,14 @@ void LLGLManager::printGLInfoString()
|
|||
std::string LLGLManager::getRawGLString()
|
||||
{
|
||||
std::string gl_string;
|
||||
gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
|
||||
if (gHeadlessClient)
|
||||
{
|
||||
gl_string = HEADLESS_VENDOR_STRING + " " + HEADLESS_RENDERER_STRING;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
|
||||
}
|
||||
return gl_string;
|
||||
}
|
||||
|
||||
|
|
@ -614,47 +648,47 @@ void LLGLManager::initExtensions()
|
|||
mHasMultitexture = TRUE;
|
||||
# else
|
||||
mHasMultitexture = FALSE;
|
||||
# endif
|
||||
# endif // GL_ARB_multitexture
|
||||
# ifdef GL_ARB_texture_env_combine
|
||||
mHasARBEnvCombine = TRUE;
|
||||
# else
|
||||
mHasARBEnvCombine = FALSE;
|
||||
# endif
|
||||
# endif // GL_ARB_texture_env_combine
|
||||
# ifdef GL_ARB_texture_compression
|
||||
mHasCompressedTextures = TRUE;
|
||||
# else
|
||||
mHasCompressedTextures = FALSE;
|
||||
# endif
|
||||
# endif // GL_ARB_texture_compression
|
||||
# ifdef GL_ARB_vertex_buffer_object
|
||||
mHasVertexBufferObject = TRUE;
|
||||
# else
|
||||
mHasVertexBufferObject = FALSE;
|
||||
# endif
|
||||
# endif // GL_ARB_vertex_buffer_object
|
||||
# ifdef GL_EXT_framebuffer_object
|
||||
mHasFramebufferObject = TRUE;
|
||||
# else
|
||||
mHasFramebufferObject = FALSE;
|
||||
# endif
|
||||
# endif // GL_EXT_framebuffer_object
|
||||
# ifdef GL_EXT_framebuffer_multisample
|
||||
mHasFramebufferMultisample = TRUE;
|
||||
# else
|
||||
mHasFramebufferMultisample = FALSE;
|
||||
# endif
|
||||
# endif // GL_EXT_framebuffer_multisample
|
||||
# ifdef GL_ARB_draw_buffers
|
||||
mHasDrawBuffers = TRUE;
|
||||
#else
|
||||
mHasDrawBuffers = FALSE;
|
||||
# endif
|
||||
# endif // GL_ARB_draw_buffers
|
||||
# if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp)
|
||||
mHasDepthClamp = TRUE;
|
||||
#else
|
||||
mHasDepthClamp = FALSE;
|
||||
#endif
|
||||
#endif // defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp)
|
||||
# if GL_EXT_blend_func_separate
|
||||
mHasBlendFuncSeparate = TRUE;
|
||||
#else
|
||||
mHasBlendFuncSeparate = FALSE;
|
||||
# endif
|
||||
# endif // GL_EXT_blend_func_separate
|
||||
mHasMipMapGeneration = FALSE;
|
||||
mHasSeparateSpecularColor = FALSE;
|
||||
mHasAnisotropic = FALSE;
|
||||
|
|
@ -1145,7 +1179,7 @@ void assert_glerror()
|
|||
}
|
||||
}
|
||||
|
||||
if (!gNoRender && gDebugGL)
|
||||
if (gDebugGL)
|
||||
{
|
||||
do_assert_glerror();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ void set_binormals(const S32 index, const U32 stride, const LLVector3 *binormals
|
|||
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
|
||||
|
||||
extern BOOL gClothRipple;
|
||||
extern BOOL gNoRender;
|
||||
extern BOOL gHeadlessClient;
|
||||
extern BOOL gGLActive;
|
||||
|
||||
#endif // LL_LLGL_H
|
||||
|
|
|
|||
|
|
@ -967,12 +967,14 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
}
|
||||
if (mTexName == 0)
|
||||
{
|
||||
llwarns << "Setting subimage on image without GL texture" << llendl;
|
||||
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
|
||||
//llwarns << "Setting subimage on image without GL texture" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
if (datap == NULL)
|
||||
{
|
||||
llwarns << "Setting subimage on image with NULL datap" << llendl;
|
||||
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
|
||||
//llwarns << "Setting subimage on image with NULL datap" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1100,6 +1102,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
//the texture is assiciate with some image by calling glTexImage outside LLImageGL
|
||||
BOOL LLImageGL::createGLTexture()
|
||||
{
|
||||
if (gHeadlessClient) return FALSE;
|
||||
if (gGLManager.mIsDisabled)
|
||||
{
|
||||
llwarns << "Trying to create a texture while GL is disabled!" << llendl;
|
||||
|
|
@ -1128,6 +1131,7 @@ BOOL LLImageGL::createGLTexture()
|
|||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
|
||||
{
|
||||
if (gHeadlessClient) return FALSE;
|
||||
if (gGLManager.mIsDisabled)
|
||||
{
|
||||
llwarns << "Trying to create a texture while GL is disabled!" << llendl;
|
||||
|
|
|
|||
|
|
@ -1,361 +1,361 @@
|
|||
/**
|
||||
* @file lldockcontrol.cpp
|
||||
* @brief Creates a panel of a specific kind for a toast
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "lldockcontrol.h"
|
||||
#include "lldockablefloater.h"
|
||||
|
||||
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
|
||||
const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
|
||||
mDockWidget(dockWidget),
|
||||
mDockableFloater(dockableFloater),
|
||||
mDockTongue(dockTongue),
|
||||
mDockTongueX(0),
|
||||
mDockTongueY(0)
|
||||
{
|
||||
mDockAt = dockAt;
|
||||
|
||||
if (dockableFloater->isDocked())
|
||||
{
|
||||
on();
|
||||
}
|
||||
else
|
||||
{
|
||||
off();
|
||||
}
|
||||
|
||||
if (!(get_allowed_rect_callback))
|
||||
{
|
||||
mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGetAllowedRectCallback = get_allowed_rect_callback;
|
||||
}
|
||||
|
||||
if (dockWidget != NULL)
|
||||
{
|
||||
repositionDockable();
|
||||
}
|
||||
|
||||
if (mDockWidget != NULL)
|
||||
{
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockWidgetVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
LLDockControl::~LLDockControl()
|
||||
{
|
||||
}
|
||||
|
||||
void LLDockControl::setDock(LLView* dockWidget)
|
||||
{
|
||||
mDockWidget = dockWidget;
|
||||
if (mDockWidget != NULL)
|
||||
{
|
||||
repositionDockable();
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockWidgetVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LLDockControl::getAllowedRect(LLRect& rect)
|
||||
{
|
||||
rect = mDockableFloater->getRootView()->getRect();
|
||||
}
|
||||
|
||||
void LLDockControl::repositionDockable()
|
||||
{
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
|
||||
// recalculate dockable position if dock position changed, dock visibility changed,
|
||||
// root view rect changed or recalculation is forced
|
||||
if (mPrevDockRect != dockRect || mDockWidgetVisible != isDockVisible()
|
||||
|| mRootRect != rootRect || mRecalculateDocablePosition)
|
||||
{
|
||||
// undock dockable and off() if dock not visible
|
||||
if (!isDockVisible())
|
||||
{
|
||||
mDockableFloater->setDocked(false);
|
||||
// force off() since dockable may not have dockControll at this time
|
||||
off();
|
||||
LLDockableFloater* dockable_floater =
|
||||
dynamic_cast<LLDockableFloater*> (mDockableFloater);
|
||||
if(dockable_floater != NULL)
|
||||
{
|
||||
dockable_floater->onDockHidden();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mEnabled)
|
||||
{
|
||||
moveDockable();
|
||||
}
|
||||
LLDockableFloater* dockable_floater =
|
||||
dynamic_cast<LLDockableFloater*> (mDockableFloater);
|
||||
if(dockable_floater != NULL)
|
||||
{
|
||||
dockable_floater->onDockShown();
|
||||
}
|
||||
}
|
||||
|
||||
mPrevDockRect = dockRect;
|
||||
mRootRect = rootRect;
|
||||
mRecalculateDocablePosition = false;
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLDockControl::isDockVisible()
|
||||
{
|
||||
bool res = true;
|
||||
|
||||
if (mDockWidget != NULL)
|
||||
{
|
||||
//we should check all hierarchy
|
||||
res = mDockWidget->isInVisibleChain();
|
||||
if (res)
|
||||
{
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
|
||||
switch (mDockAt)
|
||||
{
|
||||
case LEFT: // to keep compiler happy
|
||||
break;
|
||||
case BOTTOM:
|
||||
case TOP:
|
||||
{
|
||||
// check is dock inside parent rect
|
||||
// assume that parent for all dockable flaoters
|
||||
// is the root view
|
||||
LLRect dockParentRect =
|
||||
mDockWidget->getRootView()->calcScreenRect();
|
||||
if (dockRect.mRight <= dockParentRect.mLeft
|
||||
|| dockRect.mLeft >= dockParentRect.mRight)
|
||||
{
|
||||
res = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void LLDockControl::moveDockable()
|
||||
{
|
||||
// calculate new dockable position
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
|
||||
bool use_tongue = false;
|
||||
LLDockableFloater* dockable_floater =
|
||||
dynamic_cast<LLDockableFloater*> (mDockableFloater);
|
||||
if (dockable_floater != NULL)
|
||||
{
|
||||
use_tongue = dockable_floater->getUseTongue();
|
||||
}
|
||||
|
||||
LLRect dockableRect = mDockableFloater->calcScreenRect();
|
||||
S32 x = 0;
|
||||
S32 y = 0;
|
||||
LLRect dockParentRect;
|
||||
switch (mDockAt)
|
||||
{
|
||||
case LEFT:
|
||||
x = dockRect.mLeft;
|
||||
y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
|
||||
|
||||
mDockTongueY = dockRect.mTop;
|
||||
break;
|
||||
|
||||
case TOP:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
y = dockRect.mTop + dockableRect.getHeight();
|
||||
// unique docking used with dock tongue, so add tongue height to the Y coordinate
|
||||
if (use_tongue)
|
||||
{
|
||||
y += mDockTongue->getHeight();
|
||||
|
||||
if ( y > rootRect.mTop)
|
||||
{
|
||||
y = rootRect.mTop;
|
||||
}
|
||||
}
|
||||
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
|
||||
// calculate dock tongue position
|
||||
dockParentRect = mDockWidget->getParent()->calcScreenRect();
|
||||
if (dockRect.getCenterX() < dockParentRect.mLeft)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
else if (dockRect.getCenterX() > dockParentRect.mRight)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
mDockTongueY = dockRect.mTop;
|
||||
|
||||
break;
|
||||
case BOTTOM:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
y = dockRect.mBottom;
|
||||
// unique docking used with dock tongue, so add tongue height to the Y coordinate
|
||||
if (use_tongue)
|
||||
{
|
||||
y -= mDockTongue->getHeight();
|
||||
}
|
||||
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
// calculate dock tongue position
|
||||
dockParentRect = mDockWidget->getParent()->calcScreenRect();
|
||||
if (dockRect.getCenterX() < dockParentRect.mLeft)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
else if (dockRect.getCenterX() > dockParentRect.mRight)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
mDockTongueY = dockRect.mBottom - mDockTongue->getHeight();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
S32 max_available_height = rootRect.getHeight() - (rootRect.mBottom - mDockTongueY) - mDockTongue->getHeight();
|
||||
|
||||
// A floater should be shrunk so it doesn't cover a part of its docking tongue and
|
||||
// there is a space between a dockable floater and a control to which it is docked.
|
||||
if (use_tongue && dockableRect.getHeight() >= max_available_height)
|
||||
{
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height);
|
||||
mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
// move dockable
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
|
||||
dockableRect.getHeight());
|
||||
}
|
||||
LLRect localDocableParentRect;
|
||||
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
|
||||
&localDocableParentRect);
|
||||
mDockableFloater->setRect(localDocableParentRect);
|
||||
|
||||
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
|
||||
&mDockTongueX, &mDockTongueY);
|
||||
|
||||
}
|
||||
|
||||
void LLDockControl::on()
|
||||
{
|
||||
if (isDockVisible())
|
||||
{
|
||||
mEnabled = true;
|
||||
mRecalculateDocablePosition = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLDockControl::off()
|
||||
{
|
||||
mEnabled = false;
|
||||
}
|
||||
|
||||
void LLDockControl::forceRecalculatePosition()
|
||||
{
|
||||
mRecalculateDocablePosition = true;
|
||||
}
|
||||
|
||||
void LLDockControl::drawToungue()
|
||||
{
|
||||
bool use_tongue = false;
|
||||
LLDockableFloater* dockable_floater =
|
||||
dynamic_cast<LLDockableFloater*> (mDockableFloater);
|
||||
if (dockable_floater != NULL)
|
||||
{
|
||||
use_tongue = dockable_floater->getUseTongue();
|
||||
}
|
||||
|
||||
if (mEnabled && use_tongue)
|
||||
{
|
||||
mDockTongue->draw(mDockTongueX, mDockTongueY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @file lldockcontrol.cpp
|
||||
* @brief Creates a panel of a specific kind for a toast
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "lldockcontrol.h"
|
||||
#include "lldockablefloater.h"
|
||||
|
||||
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
|
||||
const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
|
||||
mDockWidget(dockWidget),
|
||||
mDockableFloater(dockableFloater),
|
||||
mDockTongue(dockTongue),
|
||||
mDockTongueX(0),
|
||||
mDockTongueY(0)
|
||||
{
|
||||
mDockAt = dockAt;
|
||||
|
||||
if (dockableFloater->isDocked())
|
||||
{
|
||||
on();
|
||||
}
|
||||
else
|
||||
{
|
||||
off();
|
||||
}
|
||||
|
||||
if (!(get_allowed_rect_callback))
|
||||
{
|
||||
mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGetAllowedRectCallback = get_allowed_rect_callback;
|
||||
}
|
||||
|
||||
if (dockWidget != NULL)
|
||||
{
|
||||
repositionDockable();
|
||||
}
|
||||
|
||||
if (mDockWidget != NULL)
|
||||
{
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockWidgetVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
LLDockControl::~LLDockControl()
|
||||
{
|
||||
}
|
||||
|
||||
void LLDockControl::setDock(LLView* dockWidget)
|
||||
{
|
||||
mDockWidget = dockWidget;
|
||||
if (mDockWidget != NULL)
|
||||
{
|
||||
repositionDockable();
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockWidgetVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LLDockControl::getAllowedRect(LLRect& rect)
|
||||
{
|
||||
rect = mDockableFloater->getRootView()->getRect();
|
||||
}
|
||||
|
||||
void LLDockControl::repositionDockable()
|
||||
{
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
|
||||
// recalculate dockable position if dock position changed, dock visibility changed,
|
||||
// root view rect changed or recalculation is forced
|
||||
if (mPrevDockRect != dockRect || mDockWidgetVisible != isDockVisible()
|
||||
|| mRootRect != rootRect || mRecalculateDocablePosition)
|
||||
{
|
||||
// undock dockable and off() if dock not visible
|
||||
if (!isDockVisible())
|
||||
{
|
||||
mDockableFloater->setDocked(false);
|
||||
// force off() since dockable may not have dockControll at this time
|
||||
off();
|
||||
LLDockableFloater* dockable_floater =
|
||||
dynamic_cast<LLDockableFloater*> (mDockableFloater);
|
||||
if(dockable_floater != NULL)
|
||||
{
|
||||
dockable_floater->onDockHidden();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mEnabled)
|
||||
{
|
||||
moveDockable();
|
||||
}
|
||||
LLDockableFloater* dockable_floater =
|
||||
dynamic_cast<LLDockableFloater*> (mDockableFloater);
|
||||
if(dockable_floater != NULL)
|
||||
{
|
||||
dockable_floater->onDockShown();
|
||||
}
|
||||
}
|
||||
|
||||
mPrevDockRect = dockRect;
|
||||
mRootRect = rootRect;
|
||||
mRecalculateDocablePosition = false;
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLDockControl::isDockVisible()
|
||||
{
|
||||
bool res = true;
|
||||
|
||||
if (mDockWidget != NULL)
|
||||
{
|
||||
//we should check all hierarchy
|
||||
res = mDockWidget->isInVisibleChain();
|
||||
if (res)
|
||||
{
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
|
||||
switch (mDockAt)
|
||||
{
|
||||
case LEFT: // to keep compiler happy
|
||||
break;
|
||||
case BOTTOM:
|
||||
case TOP:
|
||||
{
|
||||
// check is dock inside parent rect
|
||||
// assume that parent for all dockable flaoters
|
||||
// is the root view
|
||||
LLRect dockParentRect =
|
||||
mDockWidget->getRootView()->calcScreenRect();
|
||||
if (dockRect.mRight <= dockParentRect.mLeft
|
||||
|| dockRect.mLeft >= dockParentRect.mRight)
|
||||
{
|
||||
res = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void LLDockControl::moveDockable()
|
||||
{
|
||||
// calculate new dockable position
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
|
||||
bool use_tongue = false;
|
||||
LLDockableFloater* dockable_floater =
|
||||
dynamic_cast<LLDockableFloater*> (mDockableFloater);
|
||||
if (dockable_floater != NULL)
|
||||
{
|
||||
use_tongue = dockable_floater->getUseTongue();
|
||||
}
|
||||
|
||||
LLRect dockableRect = mDockableFloater->calcScreenRect();
|
||||
S32 x = 0;
|
||||
S32 y = 0;
|
||||
LLRect dockParentRect;
|
||||
switch (mDockAt)
|
||||
{
|
||||
case LEFT:
|
||||
x = dockRect.mLeft;
|
||||
y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
|
||||
|
||||
mDockTongueY = dockRect.mTop;
|
||||
break;
|
||||
|
||||
case TOP:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
y = dockRect.mTop + dockableRect.getHeight();
|
||||
// unique docking used with dock tongue, so add tongue height to the Y coordinate
|
||||
if (use_tongue)
|
||||
{
|
||||
y += mDockTongue->getHeight();
|
||||
|
||||
if ( y > rootRect.mTop)
|
||||
{
|
||||
y = rootRect.mTop;
|
||||
}
|
||||
}
|
||||
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
|
||||
// calculate dock tongue position
|
||||
dockParentRect = mDockWidget->getParent()->calcScreenRect();
|
||||
if (dockRect.getCenterX() < dockParentRect.mLeft)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
else if (dockRect.getCenterX() > dockParentRect.mRight)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
mDockTongueY = dockRect.mTop;
|
||||
|
||||
break;
|
||||
case BOTTOM:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
y = dockRect.mBottom;
|
||||
// unique docking used with dock tongue, so add tongue height to the Y coordinate
|
||||
if (use_tongue)
|
||||
{
|
||||
y -= mDockTongue->getHeight();
|
||||
}
|
||||
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
// calculate dock tongue position
|
||||
dockParentRect = mDockWidget->getParent()->calcScreenRect();
|
||||
if (dockRect.getCenterX() < dockParentRect.mLeft)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
else if (dockRect.getCenterX() > dockParentRect.mRight)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
mDockTongueY = dockRect.mBottom - mDockTongue->getHeight();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
S32 max_available_height = rootRect.getHeight() - (rootRect.mBottom - mDockTongueY) - mDockTongue->getHeight();
|
||||
|
||||
// A floater should be shrunk so it doesn't cover a part of its docking tongue and
|
||||
// there is a space between a dockable floater and a control to which it is docked.
|
||||
if (use_tongue && dockableRect.getHeight() >= max_available_height)
|
||||
{
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height);
|
||||
mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
// move dockable
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
|
||||
dockableRect.getHeight());
|
||||
}
|
||||
LLRect localDocableParentRect;
|
||||
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
|
||||
&localDocableParentRect);
|
||||
mDockableFloater->setRect(localDocableParentRect);
|
||||
|
||||
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
|
||||
&mDockTongueX, &mDockTongueY);
|
||||
|
||||
}
|
||||
|
||||
void LLDockControl::on()
|
||||
{
|
||||
if (isDockVisible())
|
||||
{
|
||||
mEnabled = true;
|
||||
mRecalculateDocablePosition = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLDockControl::off()
|
||||
{
|
||||
mEnabled = false;
|
||||
}
|
||||
|
||||
void LLDockControl::forceRecalculatePosition()
|
||||
{
|
||||
mRecalculateDocablePosition = true;
|
||||
}
|
||||
|
||||
void LLDockControl::drawToungue()
|
||||
{
|
||||
bool use_tongue = false;
|
||||
LLDockableFloater* dockable_floater =
|
||||
dynamic_cast<LLDockableFloater*> (mDockableFloater);
|
||||
if (dockable_floater != NULL)
|
||||
{
|
||||
use_tongue = dockable_floater->getUseTongue();
|
||||
}
|
||||
|
||||
if (mEnabled && use_tongue)
|
||||
{
|
||||
mDockTongue->draw(mDockTongueX, mDockTongueY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2869,7 +2869,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
|
|||
// close callback
|
||||
if (p.close_callback.isProvided())
|
||||
{
|
||||
mCloseSignal.connect(initCommitCallback(p.close_callback));
|
||||
setCloseCallback(initCommitCallback(p.close_callback));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2879,6 +2879,11 @@ boost::signals2::connection LLFloater::setMinimizeCallback( const commit_signal_
|
|||
return mMinimizeSignal->connect(cb);
|
||||
}
|
||||
|
||||
boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::slot_type& cb )
|
||||
{
|
||||
return mCloseSignal.connect(cb);
|
||||
}
|
||||
|
||||
LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build");
|
||||
|
||||
bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node)
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ public:
|
|||
bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL);
|
||||
|
||||
boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb );
|
||||
boost::signals2::connection setCloseCallback( const commit_signal_t::slot_type& cb );
|
||||
|
||||
void initFromParams(const LLFloater::Params& p);
|
||||
bool initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node = NULL);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,11 @@ LLFloaterRegListener::LLFloaterRegListener():
|
|||
"Ask to toggle the state of the floater specified in [\"name\"]",
|
||||
&LLFloaterRegListener::toggleInstance,
|
||||
requiredName);
|
||||
add("instanceVisible",
|
||||
"Return on [\"reply\"] an event whose [\"visible\"] indicates the visibility "
|
||||
"of the floater specified in [\"name\"]",
|
||||
&LLFloaterRegListener::instanceVisible,
|
||||
requiredName);
|
||||
LLSD requiredNameButton;
|
||||
requiredNameButton["name"] = LLSD();
|
||||
requiredNameButton["button"] = LLSD();
|
||||
|
|
@ -71,9 +76,7 @@ LLFloaterRegListener::LLFloaterRegListener():
|
|||
|
||||
void LLFloaterRegListener::getBuildMap(const LLSD& event) const
|
||||
{
|
||||
// Honor the "reqid" convention by echoing event["reqid"] in our reply packet.
|
||||
LLReqID reqID(event);
|
||||
LLSD reply(reqID.makeResponse());
|
||||
LLSD reply;
|
||||
// Build an LLSD map that mirrors sBuildMap. Since we have no good way to
|
||||
// represent a C++ callable in LLSD, the only part of BuildData we can
|
||||
// store is the filename. For each LLSD map entry, it would be more
|
||||
|
|
@ -86,7 +89,7 @@ void LLFloaterRegListener::getBuildMap(const LLSD& event) const
|
|||
reply[mi->first] = mi->second.mFile;
|
||||
}
|
||||
// Send the reply to the LLEventPump named in event["reply"].
|
||||
LLEventPumps::instance().obtain(event["reply"]).post(reply);
|
||||
sendReply(reply, event);
|
||||
}
|
||||
|
||||
void LLFloaterRegListener::showInstance(const LLSD& event) const
|
||||
|
|
@ -104,6 +107,12 @@ void LLFloaterRegListener::toggleInstance(const LLSD& event) const
|
|||
LLFloaterReg::toggleInstance(event["name"], event["key"]);
|
||||
}
|
||||
|
||||
void LLFloaterRegListener::instanceVisible(const LLSD& event) const
|
||||
{
|
||||
sendReply(LLSDMap("visible", LLFloaterReg::instanceVisible(event["name"], event["key"])),
|
||||
event);
|
||||
}
|
||||
|
||||
void LLFloaterRegListener::clickButton(const LLSD& event) const
|
||||
{
|
||||
// If the caller requests a reply, build the reply.
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ private:
|
|||
void showInstance(const LLSD& event) const;
|
||||
void hideInstance(const LLSD& event) const;
|
||||
void toggleInstance(const LLSD& event) const;
|
||||
void instanceVisible(const LLSD& event) const;
|
||||
void clickButton(const LLSD& event) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ public:
|
|||
|
||||
void setColor(const LLColor4& color) { mColor = color; }
|
||||
void setImage(LLPointer<LLUIImage> image) { mImagep = image; }
|
||||
const LLPointer<LLUIImage> getImage() { return mImagep; }
|
||||
|
||||
private:
|
||||
void setIconImageDrawSize() ;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue