/// key is the end of the interval, value is the start of the interval typedef std::map<AccessibleEventNotifier::TClientId,
AccessibleEventNotifier::TClientId> IntervalMap;
void releaseId(AccessibleEventNotifier::TClientId const nId)
{
IntervalMap & rFreeIntervals(GetFreeIntervals());
IntervalMap::iterator const upper(rFreeIntervals.upper_bound(nId));
assert(upper != rFreeIntervals.end());
assert(nId < upper->second); // second is start of the interval! if (nId + 1 == upper->second)
{
--upper->second; // add nId to existing interval
} else
{
IntervalMap::iterator const lower(rFreeIntervals.lower_bound(nId)); if (lower != rFreeIntervals.end() && lower->first == nId - 1)
{ // add nId by replacing lower with new merged entry
rFreeIntervals.insert(std::make_pair(nId, lower->second));
rFreeIntervals.erase(lower);
} else// otherwise just add new 1-element interval
{
rFreeIntervals.insert(std::make_pair(nId, nId));
}
} // currently it's not checked whether intervals can be merged now // hopefully that won't be a problem in practice
}
/// generates a new client id
AccessibleEventNotifier::TClientId generateId()
{
IntervalMap & rFreeIntervals(GetFreeIntervals());
assert(!rFreeIntervals.empty());
IntervalMap::iterator const iter(rFreeIntervals.begin());
AccessibleEventNotifier::TClientId const nFirst = iter->first;
AccessibleEventNotifier::TClientId const nFreeId = iter->second;
assert(nFreeId <= nFirst); if (nFreeId != nFirst)
{
++iter->second; // remove nFreeId from interval
} else
{
rFreeIntervals.erase(iter); // remove 1-element interval
}
ClientMap::iterator aClientPos; if (!implLookupClient(_nClient, aClientPos)) // already asserted in implLookupClient return;
// notify the listeners
ListenerContainer aListeners(std::move(aClientPos->second));
// we do not need the entry in the clients map anymore // (do this before actually notifying, because some client // implementations have re-entrance problems and call into // revokeClient while we are notifying from here)
gaClients.erase(aClientPos);
releaseId(_nClient);
// notify the "disposing" event for this client
EventObject aDisposalEvent;
aDisposalEvent.Source = _rxEventSource;
// now really do the notification
aListeners.disposeAndClear( aGuard, aDisposalEvent );
}
ClientMap::iterator aClientPos; if ( !implLookupClient( _nClient, aClientPos ) ) // already asserted in implLookupClient return;
// since we're synchronous, again, we want to notify immediately
OInterfaceIteratorHelper4 aIt(aGuard, aClientPos->second); // no need to hold lock here, and we don't want to hold lock while calling listeners
aGuard.unlock(); while (aIt.hasMoreElements())
{ try
{
aIt.next()->notifyEvent(_rEvent);
} catch (Exception&)
{ // no assertion, because a broken access remote bridge or something like this // can cause this exception
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.