mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 16:50:43 +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);
|
rightPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightPalmRotation);
|
||||||
|
|
||||||
// update thread-safe caches
|
// update thread-safe caches
|
||||||
_leftPalmRotationCache.merge([&](const glm::quat& value, bool hasPending, const glm::quat& pendingValue) {
|
_leftPalmRotationCache.set(leftPalmRotation);
|
||||||
return leftPalmRotation;
|
_rightPalmRotationCache.set(rightPalmRotation);
|
||||||
});
|
_leftPalmPositionCache.set(leftPalmPosition);
|
||||||
_rightPalmRotationCache.merge([&](const glm::quat& value, bool hasPending, const glm::quat& pendingValue) {
|
_rightPalmPositionCache.set(rightPalmPosition);
|
||||||
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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,53 +17,29 @@
|
||||||
// It allows many threads to get or set a value atomically.
|
// It allows many threads to get or set a value atomically.
|
||||||
// This provides cache semantics, any get will return the last set value.
|
// 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
|
// 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.
|
// and JavaScript which is running on a different thread.
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ThreadSafeValueCache {
|
class ThreadSafeValueCache {
|
||||||
public:
|
public:
|
||||||
ThreadSafeValueCache(const T& v) : _value { v }, _pending { v }, _hasPending { false } {}
|
ThreadSafeValueCache(const T& v) : _value { v } {}
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns atomic copy of the cached value.
|
// returns atomic copy of the cached value.
|
||||||
T get() const {
|
T get() const {
|
||||||
std::lock_guard<std::mutex> guard(_mutex);
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
if (_hasPending) {
|
|
||||||
return _pending;
|
|
||||||
} else {
|
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// will reflect copy of value into the cache.
|
// will reflect copy of value into the cache.
|
||||||
void set(const T& v) {
|
void set(const T& v) {
|
||||||
std::lock_guard<std::mutex> guard(_mutex);
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
_hasPending = true;
|
_value = v;
|
||||||
_pending = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::mutex _mutex;
|
mutable std::mutex _mutex;
|
||||||
T _value;
|
T _value;
|
||||||
T _pending;
|
|
||||||
bool _hasPending;
|
|
||||||
|
|
||||||
// no copies
|
// no copies
|
||||||
ThreadSafeValueCache(const ThreadSafeValueCache&) = delete;
|
ThreadSafeValueCache(const ThreadSafeValueCache&) = delete;
|
||||||
|
|
Loading…
Reference in a new issue