|
|
@ -37,13 +37,19 @@ class Observable { |
|
|
|
// Update the value to something new. Awakes any waiters.
|
|
|
|
// Update the value to something new. Awakes any waiters.
|
|
|
|
void Set(T value) { state_->Set(std::move(value)); } |
|
|
|
void Set(T value) { state_->Set(std::move(value)); } |
|
|
|
|
|
|
|
|
|
|
|
// Returns a promise that resolves to a T when the value becomes != current.
|
|
|
|
// Returns a promise that resolves to a T when is_acceptable returns true for
|
|
|
|
auto Next(T current) { return ObserverIfChanged(state_, std::move(current)); } |
|
|
|
// that value.
|
|
|
|
|
|
|
|
// is_acceptable is any invocable that takes a `const T&` and returns a bool.
|
|
|
|
|
|
|
|
template <typename F> |
|
|
|
|
|
|
|
auto NextWhen(F is_acceptable) { |
|
|
|
|
|
|
|
return ObserverWhen<F>(state_, std::move(is_acceptable)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Same as Next(), except it resolves only once is_acceptable returns
|
|
|
|
// Returns a promise that resolves to a T when the value becomes != current.
|
|
|
|
// true for the new value.
|
|
|
|
auto Next(T current) { |
|
|
|
auto NextWhen(absl::AnyInvocable<bool(const T&)> is_acceptable) { |
|
|
|
return NextWhen([current = std::move(current)](const T& value) { |
|
|
|
return ObserverWhen(state_, std::move(is_acceptable)); |
|
|
|
return value != current; |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
@ -145,27 +151,12 @@ class Observable { |
|
|
|
bool saw_pending_ = false; |
|
|
|
bool saw_pending_ = false; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// An observer that resolves to a T when the value becomes != current.
|
|
|
|
|
|
|
|
class ObserverIfChanged : public Observer { |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
ObserverIfChanged(RefCountedPtr<State> state, T current) |
|
|
|
|
|
|
|
: Observer(std::move(state)), current_(std::move(current)) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ObserverIfChanged(ObserverIfChanged&& other) noexcept |
|
|
|
|
|
|
|
: Observer(std::move(other)), current_(std::move(other.current_)) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ShouldReturn(const T& current) override { return current_ != current; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
T current_; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// A promise that resolves to a T when is_acceptable returns true for
|
|
|
|
// A promise that resolves to a T when is_acceptable returns true for
|
|
|
|
// the current value.
|
|
|
|
// the current value.
|
|
|
|
|
|
|
|
template <typename F> |
|
|
|
class ObserverWhen : public Observer { |
|
|
|
class ObserverWhen : public Observer { |
|
|
|
public: |
|
|
|
public: |
|
|
|
ObserverWhen(RefCountedPtr<State> state, |
|
|
|
ObserverWhen(RefCountedPtr<State> state, F is_acceptable) |
|
|
|
absl::AnyInvocable<bool(const T&)> is_acceptable) |
|
|
|
|
|
|
|
: Observer(std::move(state)), |
|
|
|
: Observer(std::move(state)), |
|
|
|
is_acceptable_(std::move(is_acceptable)) {} |
|
|
|
is_acceptable_(std::move(is_acceptable)) {} |
|
|
|
|
|
|
|
|
|
|
@ -178,7 +169,7 @@ class Observable { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
|
absl::AnyInvocable<bool(const T&)> is_acceptable_; |
|
|
|
F is_acceptable_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
RefCountedPtr<State> state_; |
|
|
|
RefCountedPtr<State> state_; |
|
|
|