Age | Commit message (Collapse) | Author |
|
While calling a C++ function with arguments taken from a runtime-variable data
structure necessarily involves a bit of hocus-pocus, the best you can say for
the boost::fusion based implementation is that it worked. Sadly, template
recursion limited its applicability to a handful of function arguments. Now
that we have LL::apply(), use that instead. This implementation is much more
straightforward.
In particular, the LLSDArgsSource class, whose job was to dole out elements of
an LLSD array one at a time for the template recursion, goes away entirely.
Make virtual LLEventDispatcher::DispatchEntry::call() return LLSD instead of
void. All LLEventDispatcher target functions so far have been void; any
function that wants to respond to its invoker must do so explicitly by calling
sendReply() or constructing an LLEventAPI::Response instance. Supporting non-
void functions permits LLEventDispatcher to respond implicitly with the
returned value. Of course this requires a wrapper for void target functions
that returns LLSD::isUndefined().
Break out LLEventDispatcher::reply() from callFail(), so we can reply with
success as well as failure.
Make LLEventDispatcher::try_call_log() prepend the actual leaf class name and
description to any error returned by three-arg try_call(). That try_call()
overload reported "LLEventDispatcher(desc): " for a couple specific errors,
but no others. Hoist to try_call_log() to apply uniformly.
Introduce new try_call_one() method to diagnose name-not-found errors and
catch internal DispatchError and LL::apply_error exceptions. try_call_one()
returns a std::pair, containing either an error message or an LLSD value.
Make try_call_log() and three-arg try_call() accept LLSD 'name' instead of
plain std::string, allowing for the possibility of an array or map. That lets
us extend three-arg try_call() to break out new cases for the function selector
LLSD: isUndefined(), isArray(), isMap() and (current case) scalar String.
If try_call_one() reports an error, log it and try to send reply, as now. If
it returns LLSD::isUndefined(), e.g. from a void target function wrapper, do
nothing. But if it returns an LLSD map, try to send that back to the invoker.
And if it returns an LLSD scalar or array, wrap it in a map with key "data" to
respond to the invoker. Allowing a target function to return its result rather
than explicitly sending it opens the possibility of batched requests
(aggregate 'name') returning batched responses.
Almost every place that constructs LLEventDispatcher's internal DispatchError
exception called stringize() to format the what() string. Simplify calls by
making DispatchError accept variadic arguments and forward to stringize().
Add LL::invoke() to apply.h. Like LL::apply(), this is a (limited) C++14
foreshadowing of std::invoke(), with preprocessor conditionals to switch to
std::invoke() when that's available. Introduce LL::invoke() to handle a
callable that's actually a pointer to method.
Now our C++14 apply() implementation can accept pointer to method, using
invoke() to generalize the actual function call.
Also anticipate std::bind_front() with LL::bind_front(). For apply(func,
std::array) and our extensions apply(func, std::vector) and apply(func, LLSD),
we can't pass a pointer to method as the func unless the second argument
happens to be an array or vector of pointers (or references) to instances of
exactly the right class -- and of course LLSD can't store such at all. It's
tempting to pass std::bind(std::mem_fn(ptr_to_method), instance), but that
won't work: std::bind() requires a value or placeholder for each argument to
pass to the bound function. The bind() expression above would only work for a
nullary method. std::bind_front() would work, but that doesn't arrive until
C++20. Again, once we get there we'll defer to the std:: implementation.
Instead of the generic __cplusplus, check the appropriate feature-test macro
for availability of each of std::invoke(), std::apply() and std::bind_front().
Change apply() error handling from assert() to new LL::apply_error exception.
LLEventDispatcher must be able to intercept apply() errors. Move validation
and synthesis of the relevant error message to new apply.cpp source file.
Add to llptrto.h new LL::get_ref() and LL::get_ptr() template functions to
unify the cases of a calling template accepting either a pointer or a
reference. Wrapping the parameter in either get_ref() or get_ptr() allows
dereferencing the parameter as desired.
Move LL::apply(function, LLSD) argument validation/manipulation to a non-
template function in llsdutil.cpp: no need to replicate that logic in the
template for every CALLABLE specialization.
The trouble with passing bind_front(std::mem_fn(ptr_to_method), instance) to
apply() is that since bind_front() accepts and forwards variadic additional
arguments, apply() can't infer the arity of the bound ptr_to_method. Address
that by introducing apply_n<arity>(function, LLSD), permitting a caller to
infer the arity of ptr_to_method and explicitly pass it to apply_n().
Polish up lleventdispatcher_test.cpp accordingly. Wrong LLSD type and wrong
number of arguments now produce different (somewhat more informative) error
messages. Moreover, passing too many entries in an LLSD array used to work:
the extra arguments used to be ignored. Now we require that the size of the
array match the arity of the target function. Change the too-many-arguments
tests from success testing to error testing.
Replace 'foreach' aka BOOST_FOREACH macro invocations with range 'for'.
Replace STRINGIZE(item0 << item1 << ...) with stringize(item0, item1, ...).
(cherry picked from commit 9c049563b5480bb7e8ed87d9313822595b479c3b)
|
|
For LLEventDispatcher::add(), use simpler std::enable_if construct that avoids
the need to restate the whole conditional.
Derive LLDispatchListener from LLEventStream, instead of containing an
instance. This sets up for LazyEventAPI. Don't allow tweaking an
LLDispatchListener (or subclass LLEventAPI) name.
(cherry-picked from af4fbc1f8a9 on the lazy-eventpump branch)
(cherry picked from commit 419e7a4230ae662b035ae771af8e7d8bceb2c8b1)
|
|
Instead of checking whether an add() parameter is exactly LLSD or LLSDMap,
check whether it's convertible to LLSD -- which handles those cases and more.
(cherry picked from commit fa168c11f64771dadc5df86d14ca2f07eba3b8ba)
(cherry picked from commit 6b5bfc1cf674fc568d86d7ed623fd7bb3ee2f646)
|
|
Previously, LLEventAPI intentionally hid all but one of the many add()
overloads supported by its LLEventDispatcher base class. The reason was that
certain of the add() methods take an optional fourth parameter that's an
LLSD::Map describing the expected parameter structure, while others take a
fourth templated parameter that's an instance getter callable. This led to
ambiguity, especially when passed an LLSDMap instance that's convertible to
LLSD but isn't literally LLSD. At the time, it was simpler to constrain the
add() methods inherited from LLEventDispatcher.
But by adding new std::enable_if constraints to certain LLEventDispatcher
add() methods, we've resolved the ambiguities, so LLEventAPI subclasses can
now use any add() overload (as claimed on the relevant Confluence page).
LLEventDispatcher comments have always loftily claimed that an instance getter
callable may return either a pointer or a reference, doesn't matter. But it
does when trying to pass the getter's result to boost::fusion::push_back(): a
reference must be wrapped with std::ref() while a pointer cannot be.
std::ref(pointer) produces errors. Introduce LLEventDispatcher::invoker::
bindable() overloads to Do The Right Thing whether passed a pointer or a
reference.
(cherry picked from commit 743f487c2e123171c9fc6d5b84d768f1d856d569)
(cherry picked from commit 8618e41b3489e321ecd70eb65ec4d9ca7e2f75c6)
|
|
Originally the LLEventAPI mechanism was primarily used for VITA testing. In
that case it was okay for the viewer to crash with LL_ERRS if the test script
passed a bad request.
With puppetry, hopefully new LEAP scripts will be written to engage
LLEventAPIs in all sorts of interesting ways. Change error handling from
LL_ERRS to LL_WARNS. Furthermore, if the incoming request contains a "reply"
key, send back an error response to the requester.
Update lleventdispatcher_test.cpp accordingly.
(cherry picked from commit de0539fcbe815ceec2041ecc9981e3adf59f2806)
(cherry picked from commit 4b60941952e97691f11806062f4bc66dd5ac8dae)
|
|
Instead of std::map<std::string, boost::shared_ptr>, use std::unique_ptr as
the mapped_type, using emplace() to store new entries. This more correctly
captures the desired semantics: we have no intention of passing around the
pointers in the map, we just want the map to delete them on destruction.
Use std::function instead of boost::function.
(cherry picked from commit 7ba53ef82db5683756e296225f0c8b838420a26e)
|
|
(cherry picked from commit 7d33e00d925614911a7602da1bd79916cc849ad7)
|
|
Add to apply_test.cpp a collect() function that incrementally accumulates an
arbitrary number of arguments into a std::vector<std::string>. Construct a
std::array<std::string> to pass it, using VAPPLY().
Clarify in header comments that LL::apply() can't call a variadic function
with arguments of dynamic size: std::vector or LLSD. The compiler can deduce
how many arguments to pass to a function with a fixed argument list; it can
deduce how many arguments to pass to a variadic function with a fixed number
of arguments. But it can't compile a call to a variadic function with an
arguments data structure whose size can vary at runtime.
(cherry picked from commit ceed33396266b123896f7cfb9b90abdf240e1eec)
|
|
Make apply(function, std::array) and apply(function, std::vector) available
even when we borrow the C++17 implementation of apply(function, std::tuple).
Add apply(function, LLSD) with interpretations:
* isUndefined() is treated as an empty array, for calling a nullary function
* scalar LLSD is treated as a single-entry array, for calling a unary function
* isArray() converts function parameters using LLSDParam
* isMap() is an error.
Add unit tests for all flavors of LL::apply().
(cherry picked from commit 3006c24251c6259d00df9e0f4f66b8a617e6026d)
|
|
Always search for python3[.exe] instead of plain 'python'. macOS Monterey no
longer bundles Python 2 at all.
Explicitly make PYTHON_EXECUTABLE a cached value so if the user edits it in
CMakeCache.txt, it won't be overwritten by indra/cmake/Python.cmake.
Do NOT set DYLD_LIBRARY_PATH for test executables! That has Bad Effects, as
discussed in https://stackoverflow.com/q/73418423/5533635. Instead, create
symlinks from build-mumble/sharedlibs/Resources -> Release/Resources and from
build-mumble/test/Resources -> ../sharedlibs/Release/Resources. For test
executables in sharedlibs/RelWithDebInfo and test/RelWithDebInfo, this
supports our dylibs' baked-in load path @executable_path/../Resources. That
load path assumes running in a standard app bundle (which the viewer in fact
does), but we've been avoiding creating an app bundle for every test program.
These symlinks allow us to continue doing that while avoiding
DYLD_LIBRARY_PATH.
Add indra/llcommon/apply.h. The LL::apply() function and its wrapper macro
VAPPLY were very useful in diagnosing the problem.
Tweak llleap_test.cpp. This source was modified extensively for diagnostic
purposes; these are the small improvements that remain.
(cherry picked from commit 15d37713b9113a6f70dde48c764df02c76e18cbc)
(cherry picked from commit a1adcf1905d1fbc5fe07ff5a627295ccfe461ac4)
|
|
Bring over part of the LLEventDispatcher work inspired by DRTVWR-558.
|
|
|
|
Newer C++ compilers have different semantics around LLSDArray's special copy
constructor, which was essential to proper LLSD nesting. In short, we can no
longer trust LLSDArray to behave correctly. Now that we have variadic
functions, get rid of LLSDArray and replace every reference with llsd::array().
|
|
|
|
# Conflicts:
# indra/integration_tests/llui_libtest/CMakeLists.txt
# indra/newview/llfloateravatarrendersettings.cpp
|
|
# Conflicts:
# indra/cmake/CMakeLists.txt
# indra/newview/skins/default/xui/es/floater_tools.xml
|
|
# Conflicts:
# indra/cmake/Copy3rdPartyLibs.cmake
# indra/cmake/FindOpenJPEG.cmake
# indra/cmake/OpenJPEG.cmake
# indra/integration_tests/llui_libtest/CMakeLists.txt
# indra/newview/CMakeLists.txt
|
|
As it happens, the change in the LLUUID::combine() algorithm introduced by one
of my previous commits is causing invalid assets creation (seen with
some clothing items, such as Shape and Universal types); obviously, the server
is using the old algorithm for UUID validation purpose of these assets.
This commit reverts LLUUID::combine() code to use LLMD5.
|
|
# Conflicts:
# indra/llcommon/llsdserialize.cpp
# indra/llcommon/llsdserialize.h
# indra/newview/llfilepicker.h
# indra/newview/llfilepicker_mac.h
# indra/newview/llfilepicker_mac.mm
|
|
# Conflicts:
# doc/contributions.txt
# indra/cmake/Copy3rdPartyLibs.cmake
# indra/cmake/FindOpenJPEG.cmake
# indra/cmake/OpenJPEG.cmake
# indra/integration_tests/llui_libtest/CMakeLists.txt
# indra/newview/CMakeLists.txt
|
|
|
|
|
|
|
|
|
|
speed matters. (#64)
This commit adds the HBXX64 and HBXX128 classes for use as a drop-in
replacement for the slow LLMD5 hashing class, where speed matters and
backward compatibility (with standard hashing algorithms) and/or
cryptographic hashing qualities are not required.
It also replaces LLMD5 with HBXX* in a few existing hot (well, ok, just
"warm" for some) paths meeting the above requirements, while paving the way for
future use cases, such as in the DRTVWR-559 and sibling branches where the slow
LLMD5 is used (e.g. to hash materials and vertex buffer cache entries), and
could be use such a (way) faster algorithm with very significant benefits and
no negative impact.
Here is the comment I added in indra/llcommon/hbxx.h:
// HBXXH* classes are to be used where speed matters and cryptographic quality
// is not required (no "one-way" guarantee, though they are likely not worst in
// this respect than MD5 which got busted and is now considered too weak). The
// xxHash code they are built upon is vectorized and about 50 times faster than
// MD5. A 64 bits hash class is also provided for when 128 bits of entropy are
// not needed. The hashes collision rate is similar to MD5's.
// See https://github.com/Cyan4973/xxHash#readme for details.
|
|
|
|
|
|
|
|
Fixes folders being invidible (missing arrange)
Fixes sroll to target not working reliably
|
|
D577 should have picked part of the changes from contribute branch, picking up the rest for the sake of branch specific crash fixes
|
|
|
|
# Conflicts:
# autobuild.xml
# indra/newview/llagent.cpp
# indra/newview/llimview.cpp
# indra/newview/llimview.h
# indra/newview/llinventoryfunctions.cpp
# indra/newview/llpanelmediasettingsgeneral.cpp
# indra/newview/pipeline.cpp
|
|
branches (#47)
Revert part of "DRTVWR-575: Address review comments on Xcode 14.1 type tweaks."
Crash was reproduced when assigning areastr to llsd, but likely present in other cases of assigning ui strings to llsd (instead of going for lluistring's result directly copy constructor was engaged and either copy or original crashed due to invalid pointers, copy shouldn't have been created).
|
|
|
|
|
|
One could argue that passing a negative index to an LLSD array should do
something other than shrug and reference element [0], but as that's legacy
behavior, it seems all too likely that the viewer sometimes relies on it.
This specific problem arises if the index passed to operator[]() is negative
-- either with the previous Integer parameter or with size_t (which of course
reinterprets the negative index as hugely positive). The non-const
ImplArray::ref() overload checks parameter 'i' and, if it appears negative,
sets internal 'index' to 0.
But in the next stanza, if (index >= existing size()), it calls resize() to
scale the internal array up to one more than the requested index. The trouble
is that it passed resize(i + 1), not the adjusted resize(index + 1).
With a requested index of exactly -1, that would pass resize(0), which would
result in the ensuing array[0] reference being invalid.
With a requested index less than -1, that would pass resize(hugely positive)
-- since, whether operator[]() accepts signed LLSD::Integer or size_t,
resize() accepts std::vector::size_type. Given that the footprint of an LLSD
array element is at least a pointer, the number of bytes required for
resize(hugely positive) is likely to exceed available heap storage.
Passing the adjusted resize(index + 1) should defend against that case.
|
|
The compiler was deducing an unsigned type for the difference (U64 desired
microseconds - half KERNEL_SLEEP_INTERVAL_US). When the desired sleep was less
than that constant, the difference went hugely positive, resulting in a very
long snooze.
Amusingly, forcing that U64 result into an S32 num_sleep_intervals worked only
*because* of integer truncation: the high-order bits were discarded, resulting
in a negative result as intended.
Ensuring that both integer operands are signed at the outset, though, produces
a more formally correct result.
|
|
# Conflicts:
# doc/contributions.txt
# indra/newview/llappviewer.cpp
# indra/newview/skins/default/colors.xml
|
|
|
|
# Conflicts:
# doc/contributions.txt
# indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
# indra/newview/llfloater360capture.cpp
|
|
|
|
Looks like pollTick tried to call an already dead process
|
|
|
|
The unsigned index arithmetic was problematic in that case.
|
|
|
|
Since LLSDSerialize::SIZE_UNLIMITED is negative, passing that through unsigned
size_t parameters could result in peculiar behavior.
|
|
and use it to replace dubious loops in asLLSD() and trimEmpty().
|
|
|
|
|
|
|