Skip to content
Snippets Groups Projects
This project is mirrored from https://git.alchemyviewer.org/alchemy/alchemy-next.git. Pull mirroring failed .
Repository mirroring has been paused due to too many failed attempts. It can be resumed by a project maintainer or owner.
  1. Oct 29, 2023
    • Nat Goodspeed's avatar
      DRTVWR-587: Fix LL::apply(function, LLSD array). · f7d2d40b
      Nat Goodspeed authored
      We define a specialization of LLSDParam<const char*> to support passing an
      LLSD object to a const char* function parameter. Needless to remark, passing
      object.asString().c_str() would be Bad: destroying the temporary std::string
      returned by asString() would immediately invalidate the pointer returned by
      its c_str(). But when you pass LLSDParam<const char*>(object) as the
      parameter, that specialization itself stores the std::string so the c_str()
      pointer remains valid as long as the LLSDParam object does.
      
      Then there's LLSDParam<LLSD>, used when we don't have the parameter type
      available to select the LLSDParam specialization. LLSDParam<LLSD> defines a
      templated conversion operator T() that constructs an LLSDParam<T> to provide
      the actual parameter value. So far, so good.
      
      The trouble was with the implementation of LLSDParam<LLSD>: it constructed a
      _temporary_ LLSDParam<T>, implicitly called its operator T() and immediately
      destroyed it. Destroying LLSDParam<const char*> destroyed its stored string,
      thus invalidating the c_str() pointer before the target function was entered.
      
      Instead, make LLSDParam<LLSD>::operator T() capture each LLSDParam<T> it
      constructs, extending its lifespan to the lifespan of the LLSDParam<LLSD>
      instance. For this, derive each LLSDParam specialization from LLSDParamBase, a
      trivial base class that simply establishes the virtual destructor. We can then
      capture any specialization as a pointer to LLSDParamBase.
      
      Also restore LazyEventAPI tests on Mac.
      f7d2d40b
  2. Oct 27, 2023
  3. Oct 25, 2023
  4. Oct 17, 2023
  5. Oct 12, 2023
    • Nat Goodspeed's avatar
      SL-18837: Unify all llrand_test.cpp in-range tests. · f5a34fd0
      Nat Goodspeed authored
      The header file documents that no llrand function should ever return a value
      equal to the passed extent, so the one test in llrand_test.cpp that checked
      less than or equal to the high end of the range was anomalous.
      
      But changing that to an exclusive range means that we no longer need separate
      exclusive range and inclusive range functions. Replace
      ensure_in_range_using(), ensure_in_exc_range() and ensure_in_inc_range() with
      a grand unified (simplified) ensure_in_range() function.
      f5a34fd0
  6. Oct 05, 2023
    • Nat Goodspeed's avatar
      SL-18837: When llrand_test.cpp fails, display the failing value. · 7504b1c3
      Nat Goodspeed authored
      It's frustrating and unactionable to have a failing test report merely that
      the random value was greater than the specified high end. Okay, so what was
      the value? If it's supposed to be less than the high end, did it happen to be
      equal? Or was it garbage? We can't reproduce the failure by rerunning!
      
      The new ensure_in_exc_range(), ensure_in_inc_range() mechanism is somewhat
      complex because exactly one test allows equality with the high end of the
      expected range, where the rest mandate that the function return less than the
      high end. If that's a bug in the test -- if every llrand function is supposed
      to return less than the high end -- then we could simplify the test logic.
      7504b1c3
  7. Oct 03, 2023
  8. Sep 08, 2023
    • Nat Goodspeed's avatar
      SL-18837: Make llsdserialize_test debug output conditional. · c7546ea6
      Nat Goodspeed authored
      Move hexdump() and hexmix() stream formatters to new hexdump.h for potential
      use by other tests.
      
      In toPythonUsing() helper function, add a temp file to receive Python script
      debug output, and direct debug output to that file. On test failure, dump the
      contents of that file to the log.
      
      Give NamedTempFile::peep() an optional target std::ostream; refactor
      implementation as peep_via() that accepts a callable to process each text
      line. Add operator<<() to stream the contents of a NamedTempFile object to
      ostream -- but don't use that with LL_DEBUGS(), as it flattens the file
      contents into a single log line. Instead add peep_log(), which streams each
      individual text line to LL_DEBUGS().
      c7546ea6
    • Nat Goodspeed's avatar
  9. Sep 07, 2023
  10. Aug 31, 2023
  11. Aug 29, 2023
  12. Jul 31, 2023
  13. Jul 28, 2023
  14. Jul 27, 2023
  15. Jul 26, 2023
    • Nat Goodspeed's avatar
      DRTVWR-587: Move constexpr arity into lambda that uses it. · 861cf0a5
      Nat Goodspeed authored
      VC doesn't recognize that a constexpr name doesn't need to be bound into a
      lambda. However, since it's knowable at compile time, it can be deduced within
      the innermost lambda.
      
      (cherry picked from commit 37c3daff1a565eaafee691dfb57702b6b8f024d6)
      861cf0a5
  16. Jul 24, 2023
  17. Jul 18, 2023
  18. Jul 17, 2023
  19. Jul 14, 2023
  20. Jul 13, 2023
    • Nat Goodspeed's avatar
      DRTVWR-558: Constrain LL::apply()'s use of std::apply(). · 3b46c892
      Nat Goodspeed authored
      Once std::apply() becomes available, 'using std::apply;' isn't correct because
      the more general template tries to handle the apply(function, vector) case
      that we explicitly implement below. Have to provide apply(function, tuple) and
      apply(function, array) signatures that can forward to std::apply().
      3b46c892
    • Nat Goodspeed's avatar
    • Nat Goodspeed's avatar
      DRTVWR-558: Avoid extra copy of getMetadata() LLSD map. · 3fce3d14
      Nat Goodspeed authored
      (cherry picked from commit 2c1253c8ed2a1648317e6edd768b3fda00c56ce2)
      3fce3d14
    • Nat Goodspeed's avatar
      DRTVWR-558: Fix LLEventDispatcher::addMethod() for LazyEventAPI. · 25ee39dc
      Nat Goodspeed authored
      addMethod() was using dynamic_cast<target class*>(this) and testing for
      nullptr to decide whether the class owning the passed method is, or is not, a
      subclass of LLEventDispatcher. The trouble is that it doesn't work for the
      deferred add() calls queued by LazyEventAPI: the dynamic_cast was always
      returning nullptr. static_cast works better, but that leaves us with the
      problem we were trying to solve with dynamic_cast: what if the target class
      really isn't a subclass? Use std::is_base_of to pick which of two addMethod()
      overloads to invoke, one of which calls addFail().
      
      (cherry picked from commit a4d520aa5d023d80cfeec4f40c3464b54cbcfc5b)
      25ee39dc
    • Nat Goodspeed's avatar
      DRTVWR-558: Fix const-ness glitch in LL::apply(func, tuple) · d2738b60
      Nat Goodspeed authored
      std::get<I>(const tuple) injects const into the type of each returned tuple
      element. Need to get a non-const ref to the tuple param to get the true type.
      
      (cherry picked from commit 6dda39065d3ee231998cb8a2896f94e8a45c9a82)
      d2738b60
    • Nat Goodspeed's avatar
      DRTVWR-558: Fix merge glitch: missing LLEventDispatcher::addFail() · 7c79d7a7
      Nat Goodspeed authored
      (cherry picked from commit 3be250da90dd3d361df713056b881e017684e2b3)
      7c79d7a7
    • Nat Goodspeed's avatar
      DRTVWR-558: Nail down LLDispatchListener exception handling · 2eb0ea95
      Nat Goodspeed authored
      for exceptions other than those thrown by base-class LLEventDispatcher.
      
      Explain in LLDispatchListener Doxygen comments that for a request lacking a
      "reply" key, any exception is allowed to propagate because it's likely to
      reach the post() call that triggered the exception in the first place.
      
      For batch LLDispatchListener operations, catch not only LLEventDispatcher::
      DispatchError exceptions but any std::exception, so we can collect them to
      report to the invoker. "Gotta catch 'em all!"
      
      Make LLLeap catch any std::exception thrown by processing a request from the
      plugin child process, log it and send a reply to the plugin. No plugin should
      be allowed to crash the viewer.
      
      (cherry picked from commit 94e10fd039b79f71ed8d7e10807b6e4eebd1928c)
      2eb0ea95
    • Nat Goodspeed's avatar
      DRTVWR-558: Enrich LLEventDispatcher::callFail() with current call. · c747ff09
      Nat Goodspeed authored
      Now an LLEventAPI subclass method can call callFail(...) to report an error,
      and the error will be annotated with the leaf class name, the instance name
      and the way the method was reached. The enriched error message will be logged
      and either sent back to the invoker or propagated as an exception, depending
      on the invocation tactic. In other words, a business method can use callFail()
      to Do The Right Thing according to the LLEventDispatcher contract.
      
      Introduce a nested SetState RAII class to set and clear transient state.
      SetState's constructor accepts variadic stringize() arguments. The resulting
      message is passed to LLEventDispatcher::setState(), which requires a SetState
      reference because ONLY SetState should call setState(): state data really is
      intended to be transient. SetState guarantees it will be cleared every time
      it's set.
      
      setState() respects previously-set transient state. If a call from an inner
      function finds that transient state was already set by some ancestor, it
      ignores the call and informs the caller by returning false. This lets a given
      SetState instance recognize whether it is responsible for clearing the current
      transient state.
      
      operator<<(std::ostream&, const LLEventDispatcher&) now appends getState() to
      the data reported by streaming *this. Non-static LLEventDispatcher::callFail()
      already prepends *this to the reported error message.
      
      Transient state is managed by a fiber_specific_ptr, since different threads
      and even different fibers within a thread might be concurrently performing
      different operations on the same LLEventDispatcher.
      
      Introduce a back pointer to the parent LLEventDispatcher in DispatchEntry.
      Populate it with a new constructor parameter, propagated through every
      subclass constructor. Hoist ParamsDispatchEntry::callFail() up into its
      DispatchEntry base class. Make it call non-static LLEventDispatcher::
      callFail(), which prepends the reported error with instance and transient
      state info. Use DispatchEntry::callFail() in LLSDDispatchEntry::call(),
      instead of redundantly calling LLEventDispatcher::callFail().
      
      Similarly, introduce an LLEventDispatcher back pointer into LLSDArgsMapper for
      use by its own callFail() method.
      
      The above should (!) eliminate the need to replicate LLEventDispatcher
      instance info into every helper object's descriptive strings. In particular,
      since the previous info was stored in each object by its constructor, it
      couldn't report associated transient information about how the subject
      callable was actually reached. Traversing a back pointer to the live
      LLEventDispatcher instance gets us the most current state.
      
      Make the internal three-argument LLEventDispatcher::try_call() method, which
      implements each of the operator()() and public try_call() methods, use
      SetState to append "[name]" (for explicit operator()(name, event) calls) or
      "[key=name]" (for implicit operator()(event) calls) to streamed *this.
      
      In the new LLDispatchListener request array and request map operations, use
      SetState to indicate the current entry in the array or map, overriding the
      lower-level state set by three-argument LLEventDispatcher::try_call().
      
      (cherry picked from commit 2f8d7d20f43ab411ea0fe8b756cb696954acfb3e)
      c747ff09
    • Nat Goodspeed's avatar
      DRTVWR-558: Extend LLEventDispatcher::add() overloads. · 2c894ecb
      Nat Goodspeed authored
      Add LL::always_return<T>(), which takes a callable and variadic arguments. It
      calls the callable with those arguments and, if the returned type is
      convertible to T, converts it and returns it. Otherwise it returns T().
      always_return() is generalized from, and supersedes,
      LLEventDispatcher::ReturnLLSD.
      
      Add LL::function_arity<CALLABLE>, which extends
      boost::function_types::function_arity by reporting results for both
      std::function<CALLABLE> and boost::function<CALLABLE>. Use for
      LL::apply(function, LLSD array) as well as for LLEventDispatcher.
      
      Make LLEventDispatcher::add() overloads uniformly distinguish between a
      callable (whether non-static member function or otherwise) that accepts a
      single LLSD parameter, versus any other signature. Accepting exactly one LLSD
      parameter signals that the callable will accept the composite arguments LLSD
      blob, instead of asking LLEventDispatcher to unpack the arguments blob into
      individual arguments.
      
      Support add(subclass method) overloads for arbitrary-parameters methods as
      well as for (const LLSD&) methods. Update tests accordingly: we need no longer
      pass the boilerplate lambda instance getter that binds and returns 'this'.
      
      Extract to the two LLEventDispatcher::make_invoker() overloads the LL::apply()
      logic formerly found in ReturnLLSD.
      
      Change lleventdispatcher_test.cpp tests from boost::bind(), which accepts
      variadic arguments (even though it only passes a fixed set to the target
      callable), to fixed-signature lambdas. This is because the revamped add()
      overloads care about signature.
      
      Add a test for a non-static method that accepts (const LLSD&), in other words
      the composite arguments LLSD blob, and likewise returns LLSD.
      
      (cherry picked from commit 95b787f7d7226ee9de79dfc9816f33c8bf199aad)
      2c894ecb
    • Nat Goodspeed's avatar
      DRTVWR-558: Add tests for batched LLDispatchListener operations. · b36deb79
      Nat Goodspeed authored
      Specifically, add tests for:
      
      - successful map batch
      - map batch with some errors and a reply pump
      - map batch with some errors and no reply
      - successful array batch
      - array batch with some errors and a reply pump
      - array batch with some errors and no reply
      
      (cherry picked from commit 078f0f5c9fb5075a8ad01cac417e1d7ee2b6a919)
      b36deb79
    • Nat Goodspeed's avatar
      DRTVWR-558: Make DispatchResult methods use their arguments. · 98793b8d
      Nat Goodspeed authored
      Fix lleventdispatcher_test.cpp's test class DispatchResult::strfunc(),
      intfunc(), mapfunc() and arrayfunc() to return values derived from (not
      identical to) their arguments, so we can reuse these functions for further
      testing of passing arguments to a named callable. Adjust existing tests
      accordingly.
      
      (cherry picked from commit 07e09a8daea008d28b97399920db60a147cf75c0)
      98793b8d
Loading