Skip to content
Snippets Groups Projects
Commit a02ccbf1 authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

DRTVWR-558: Support LLStoreListener<LLSD>, add LLCaptureListener.

LLStoreListener<LLSD> didn't work because of an ambiguity problem. Resolve
that by introducing an internal storeTarget() method.

Introduce LLCaptureListener<T> that's both an LLStoreListener and the variable
into which to capture the expected result. Introduce LLVarHolder<T> to contain
the variable, so we can guarantee the actual data member will be fully
constructed by the time we want to pass it to the LLStoreListener base class.

(cherry picked from commit a894703188a7755bb9acb897d6c31ae1af6efce0)
parent 8ac35b62
No related branches found
No related tags found
2 merge requests!3Update to main branch,!2Rebase onto current main branch
......@@ -435,16 +435,61 @@ class LLStoreListener: public LLEventFilter
// generic type-appropriate store through mTarget, construct an
// LLSDParam<T> and store that, thus engaging LLSDParam's custom
// conversions.
mTarget = LLSDParam<T>(llsd::drill(event, mPath));
storeTarget(LLSDParam<T>(llsd::drill(event, mPath)));
return mConsume;
}
private:
// This method disambiguates LLStoreListener<LLSD>. Directly assigning
// some_LLSD_var = LLSDParam<LLSD>(some_LLSD_value);
// is problematic because the compiler has too many choices: LLSD has
// multiple assignment operator overloads, and LLSDParam<LLSD> has a
// templated conversion operator. But LLSDParam<LLSD> can convert to a
// (const LLSD&) parameter, and LLSD::operator=(const LLSD&) works.
void storeTarget(const T& value)
{
mTarget = value;
}
T& mTarget;
const LLSD mPath;
const bool mConsume;
};
/**
* LLVarHolder bundles a target variable of the specified type. We use it as a
* base class so the target variable will be fully constructed by the time a
* subclass constructor tries to pass a reference to some other base class.
*/
template <typename T>
struct LLVarHolder
{
T mVar;
};
/**
* LLCaptureListener isa LLStoreListener that bundles the target variable of
* interest.
*/
template <typename T>
class LLCaptureListener: public LLVarHolder<T>,
public LLStoreListener<T>
{
private:
using holder = LLVarHolder<T>;
using super = LLStoreListener<T>;
public:
LLCaptureListener(const LLSD& path=LLSD(), bool consume=false):
super(*this, holder::mVar, path, consume)
{}
void set(T&& newval=T()) { holder::mVar = std::forward<T>(newval); }
const T& get() const { return holder::mVar; }
operator const T&() { return holder::mVar; }
};
/*****************************************************************************
* LLEventLogProxy
*****************************************************************************/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment