Example #1
0
void EventManager<T>::fire(EventPtr ev) {
	mUnprocessed.push(ev);
	SILOG(task,debug,"**** Firing event " << (void*)(&(*ev)) <<
		" with " << ev->getId());

	if (mEventCV && mEventLock && !mCleanup) {
		boost::mutex *lock = (boost::mutex *)mEventLock;
		boost::condition_variable *cv = (boost::condition_variable *)mEventCV;
		if (++mPendingEvents == 1) {
			boost::unique_lock<boost::mutex> waitforevent (*lock);
			// we are the first ones to fire an event.
			cv->notify_one();
		}
	}
};
Example #2
0
void EventManager<T>::temporary_processEventQueue(AbsTime forceCompletionBy) {
	AbsTime startTime = AbsTime::now();
	SILOG(task,insane," >>> Processing events.");

	// swaps to allow people to keep adding new events
	typename EventList::NodeIterator processingList(mUnprocessed);

	// The events are swapped first to guarantee that listeners are at least as up-to-date as events.
	// Events can be delayed, but we cannot allow any lost subscriptions/unsubscriptions.

	{
		typename ListenerRequestList::NodeIterator procListeners(mListenerRequests);

		const ListenerRequest *req;
		while ((req = procListeners.next()) != NULL) {
			if (req->subscription) {
				SILOG(task,debug," >>>\tDoing subscription listener "<< req->listenerId << " for event " << req->eventId << " (" << req->onlyPrimary <<  ").");
				doSubscribeId(*req);
			} else {
				SILOGNOCR(task,debug," >>>\t");
				if (req->notifyListener) {
					SILOGNOCR(task,debug,"Notifying");
				}
				SILOG(task,debug,"UNSUBSCRIBED listener " << req->listenerId << ".");
				doUnsubscribe(req->listenerId, req->notifyListener);
			}
		}
	}

	if (SILOGP(task,insane)){
		SILOG(task,insane,"==== All Event Subscribers for " << (intptr_t)this << " ====");
		typename PrimaryListenerMap::const_iterator priIter =
			mListeners.begin();
		while (priIter != mListeners.end()) {
			SILOG(task,insane,"  ID " << (*priIter).first << ":");
			PartiallyOrderedListenerList *primaryLists =
				&((*priIter).second->first);
			SecondaryListenerMap *secondaryMap =
				&((*priIter).second->second);

			for (int i = 0; i < NUM_EVENTORDER; i++) {
				ListenerList *currentList = &(primaryLists->get(i));
				for (typename ListenerList::const_iterator iter = currentList->begin();
						iter != currentList->end(); ++iter) {
					SILOG(task,insane," \t"
						"[" << (i==MIDDLE?'=':i<MIDDLE?'*':'/') << "] " <<
						(*iter).second);
				}
			}

			typename SecondaryListenerMap::const_iterator secIter;
			secIter = secondaryMap->begin();
			while (secIter != secondaryMap->end()) {
				SILOG(task,insane,"\tSec ID " << (*secIter).first << ":");
				for (int i = 0; i < NUM_EVENTORDER; i++) {
					ListenerList *currentList = &((*secIter).second->get(i));
					for (typename ListenerList::const_iterator iter = currentList->begin();
							iter != currentList->end(); ++iter) {
						SILOG(task,insane," \t\t"
							"[" << (i==MIDDLE?'=':i<MIDDLE?'*':'/') << "] " <<
							(*iter).second);
					}
				}
				++secIter;
			}
			++priIter;
		}
		SILOG(task,insane,"==== ---------------------------------- ====");
	}

	EventPtr *evTemp;
	int numProcessed = 0;

	while ((evTemp = processingList.next())!=NULL) {
		EventPtr ev (*evTemp);
		++numProcessed;

		typename PrimaryListenerMap::iterator priIter =
			mListeners.find(ev->getId().mPriId);
		if (priIter == mListeners.end()) {
			// FIXME: Should this ever happen?
			SILOG(task,warning," >>>\tWARNING: No listeners for type " <<
                  "event type " << ev->getId().mPriId);
			continue;
		}

		PartiallyOrderedListenerList *primaryLists =
			&((*priIter).second->first);
		SecondaryListenerMap *secondaryMap =
			&((*priIter).second->second);

		typename SecondaryListenerMap::iterator secIter;
		secIter = secondaryMap->find(ev->getId().mSecId);

        bool cancel = false;
        EventHistory eventHistory=EVENT_UNHANDLED;
		// Call once per event order.
		for (int i = 0; i < NUM_EVENTORDER && cancel == false; i++) {
			SILOG(task,debug," >>>\tFiring " << ev << ": " << ev->getId() <<
                  " [order " << i << "]");
			ListenerList *currentList = &(primaryLists->get(i));
			if (!currentList->empty())
				eventHistory=EVENT_HANDLED;
			if (callAllListeners(ev, currentList, forceCompletionBy)) {
				cancel = cancel || true;
			}

			if (secIter != secondaryMap->end() &&
					!(*secIter).second->get(i).empty()) {
				currentList = &((*secIter).second->get(i));
				if (!currentList->empty())
					eventHistory=EVENT_HANDLED;

				if (callAllListeners(ev, currentList, forceCompletionBy)) {
					cancel = cancel || true;
				}
				// all listeners may have returned false.
				// cleanUp(secondaryMap, secIter);
				// secIter = secondaryMap->find(ev->getId().mSecId);
			}

			if (cancel) {
				SILOG(task,debug," >>>\tCancelling " << ev->getId());
			}
		}
		if (secIter != secondaryMap->end()) {
			cleanUp(secondaryMap, secIter);
		}

        if (cancel) eventHistory=EVENT_CANCELED;
        (*ev)(eventHistory);
		SILOG(task,debug," >>>\tFinished " << ev->getId());
	}

	if (mEventCV) {
		mPendingEvents -= numProcessed;
	}

	AbsTime finishTime = AbsTime::now();
	SILOG(task,insane, "**** Done processing events this round. " <<
          "Took " << (finishTime-startTime).toSeconds() <<
		" seconds.");
}