55 Notifier() : notifyingObservers(
false), waiteeCount(0) {}
62 std::lock_guard<std::mutex> lock(m);
63 observers.push_back(observer);
71 std::unique_lock<std::mutex> lock(m);
73#if (AI_BUILD_TYPE == AI_DEBUG)
74 if (dispatcher && dispatcher->invokedFromDispatcherThread())
76 throw std::logic_error(
"AI notifier: potential deadlock as this method should not be called from the dispatcher call");
80 for(
size_t i = 0; i < observers.size(); ++i)
82 if(observers[i].lock() == observer)
84 observers.erase(observers.begin() + i);
91 if (notifyingObservers)
97 }
while(notifyingObservers);
108 std::lock_guard<std::mutex> lock(m);
109 dispatcher = dispatcher_;
114 template<
typename F,
typename... Args>
115 void notify(F f, Args&&... args)
117 notify_impl(std::bind(f, std::placeholders::_1, std::forward<Args>(args)...));
128 void notify_impl(std::function<
void (
const std::shared_ptr<T>&)> fun)
130 std::unique_lock<std::mutex> lock(m);
134 throw std::logic_error(
"You must set a dispatcher before you can produce events.");
138 decltype(observers) observersCopy;
142 using namespace std::placeholders;
143 copy_if(observers.begin(), observers.end(), back_inserter(observersCopy), bind(&weak_ptr<T>::use_count, _1));
146 if(observers.size() != observersCopy.size())
148 observers = observersCopy;
151 notifyingObservers =
true;
171 std::vector<std::shared_ptr<T>> observerStrongPtrs;
173 for(
auto o = observersCopy.cbegin(); o != observersCopy.cend(); ++o)
175 std::shared_ptr<T> strong = o->lock();
178 dispatcher->post(std::bind(fun, strong));
180 observerStrongPtrs.push_back(strong);
184 if (dispatcher && (waiteeCount > 0))
192 notifyingObservers =
false;
202 std::shared_ptr<IDispatcher> dispatcher;
206 std::deque<std::weak_ptr<T>> observers;
208 std::condition_variable cv;
209 bool notifyingObservers;
210 unsigned int waiteeCount;