mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Simplified implementation of ThreadSafeValueCache
This commit is contained in:
parent
9ea6079c64
commit
a21b604746
2 changed files with 7 additions and 39 deletions
|
@ -1198,16 +1198,8 @@ void Avatar::updatePalms() {
|
|||
rightPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightPalmRotation);
|
||||
|
||||
// update thread-safe caches
|
||||
_leftPalmRotationCache.merge([&](const glm::quat& value, bool hasPending, const glm::quat& pendingValue) {
|
||||
return leftPalmRotation;
|
||||
});
|
||||
_rightPalmRotationCache.merge([&](const glm::quat& value, bool hasPending, const glm::quat& pendingValue) {
|
||||
return rightPalmRotation;
|
||||
});
|
||||
_leftPalmPositionCache.merge([&](const glm::vec3& value, bool hasPending, const glm::vec3& pendingValue) {
|
||||
return leftPalmPosition;
|
||||
});
|
||||
_rightPalmPositionCache.merge([&](const glm::vec3& value, bool hasPending, const glm::vec3& pendingValue) {
|
||||
return rightPalmPosition;
|
||||
});
|
||||
_leftPalmRotationCache.set(leftPalmRotation);
|
||||
_rightPalmRotationCache.set(rightPalmRotation);
|
||||
_leftPalmPositionCache.set(leftPalmPosition);
|
||||
_rightPalmPositionCache.set(rightPalmPosition);
|
||||
}
|
||||
|
|
|
@ -17,53 +17,29 @@
|
|||
// It allows many threads to get or set a value atomically.
|
||||
// This provides cache semantics, any get will return the last set value.
|
||||
//
|
||||
// It also provides a mechanism for the owner of the cached value to reconcile
|
||||
// the cached value with it's own internal values, via the merge method.
|
||||
//
|
||||
// For example: This can be used to copy values between C++ code running on the application thread
|
||||
// and JavaScript which is running on a different thread.
|
||||
|
||||
template <typename T>
|
||||
class ThreadSafeValueCache {
|
||||
public:
|
||||
ThreadSafeValueCache(const T& v) : _value { v }, _pending { v }, _hasPending { false } {}
|
||||
|
||||
// The callback function should have the following prototype.
|
||||
// T func(const T& value, bool hasPending, const T& pendingValue);
|
||||
// It will be called synchronously on the current thread possibly blocking it for a short time.
|
||||
// it gives thread-safe access to the internal cache value, as well as the pending cache value
|
||||
// that was set via the last set call. This gives the cache's owner the opportunity to update
|
||||
// the cached value by resolving it with it's own internal state. The owner should then return
|
||||
// the resolved value which will be atomically reflected into the cache.
|
||||
template <typename F>
|
||||
void merge(F func) {
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
_value = func((const T&)_value, _hasPending, (const T&)_pending);
|
||||
_hasPending = false;
|
||||
}
|
||||
ThreadSafeValueCache(const T& v) : _value { v } {}
|
||||
|
||||
// returns atomic copy of the cached value.
|
||||
T get() const {
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
if (_hasPending) {
|
||||
return _pending;
|
||||
} else {
|
||||
return _value;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
// will reflect copy of value into the cache.
|
||||
void set(const T& v) {
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
_hasPending = true;
|
||||
_pending = v;
|
||||
_value = v;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::mutex _mutex;
|
||||
T _value;
|
||||
T _pending;
|
||||
bool _hasPending;
|
||||
|
||||
// no copies
|
||||
ThreadSafeValueCache(const ThreadSafeValueCache&) = delete;
|
||||
|
|
Loading…
Reference in a new issue