2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <folly/Synchronized.h>
19 #include <folly/futures/Future.h>
23 namespace observer_detail {
25 class ObserverManager;
28 * Core stores the current version of the object held by Observer. It also keeps
29 * all dependencies and dependents of the Observer.
31 class Core : public std::enable_shared_from_this<Core> {
33 using Ptr = std::shared_ptr<Core>;
34 using WeakPtr = std::weak_ptr<Core>;
37 * Blocks until creator is successfully run by ObserverManager
39 static Ptr create(folly::Function<std::shared_ptr<const void>()> creator);
42 * View of the observed object and its version
44 struct VersionedData {
47 VersionedData(std::shared_ptr<const void> data_, size_t version_)
48 : data(std::move(data_)), version(version_) {}
50 std::shared_ptr<const void> data;
55 * Gets current view of the observed object.
56 * This is safe to call from any thread. If this is called from other Observer
57 * functor then that Observer is marked as dependent on current Observer.
59 VersionedData getData();
62 * Gets the version of the observed object.
64 size_t getVersion() const {
69 * Get the last version at which the observed object was actually changed.
71 size_t getVersionLastChange() {
72 return versionLastChange_;
76 * Check if the observed object needs to be re-computed. Returns the version
77 * of last change. If force is true, re-computes the observed object, even if
78 * dependencies didn't change.
80 * This should be only called from ObserverManager thread.
82 size_t refresh(size_t version, bool force = false);
87 explicit Core(folly::Function<std::shared_ptr<const void>()> creator);
89 void addDependent(Core::WeakPtr dependent);
90 void removeStaleDependents();
92 using Dependents = std::vector<WeakPtr>;
93 using Dependencies = std::unordered_set<Ptr>;
95 folly::Synchronized<Dependents> dependents_;
96 folly::Synchronized<Dependencies> dependencies_;
98 std::atomic<size_t> version_{0};
99 std::atomic<size_t> versionLastChange_{0};
101 folly::Synchronized<VersionedData> data_;
103 folly::Function<std::shared_ptr<const void>()> creator_;
105 std::mutex refreshMutex_;