///////////////////////////////////////////////////////////////////////////////
// Attach - Associate an observer with this subject
Error CSubject::Attach(IObserver* pObserver, 
                       System::Types::BitMask inInterest, 
                       u32 uID, 
                       u32 shift)
{
    // To make compiler happy in release builds while keeping the next assertion
    UNREFERENCED_PARAM (shift);

    // If the following assertion fails, it means that Change Control Manager (CCM)
    // was modified to start using "shifts". Please update the code of this class
    // appropriately (original version did not have any meaningful support except
    // shifting inInterest on entry)
    ASSERT (!shift && "CSubject::Attach: Interest bits are shifted. Read the comment to this assertion");

    // Since the intended usage model is to use this method from CCMs only, and 
    // their implementation provided by this framework ensures that pObs in nonzero
    // the following assertion should suffice.
    ASSERT( pObserver && "CSubject::Attach: Valid pointer to observer object must be specified" );

#if SUPPORT_CONCURRENT_ATTACH_DETACH_TO_SUBJECTS
    SpinWait::Lock lock(m_observerListMutex);
#endif

    // Framework's CCM implementation ensures that the following assertion always holds
    ASSERT( std::find(m_observerList.begin(), m_observerList.end(), pObserver) == m_observerList.end() &&
            "CSubject::Attach: Observer has already been attached. Use CSubject::UpdateInterestBits instead." );

    // Add the observer to our list of observers
    m_observerList.push_back( ObserverRequest(pObserver, inInterest, uID) );

    return Errors::Success;
}
///////////////////////////////////////////////////////////////////////////////
// Register - Register a new subject/observer relationsship
Error ChangeManager::Register(ISubject* pInSubject, System::Changes::BitMask observerIntrestBits, IObserver* pInObserver, System::Types::BitMask observerIdBits) {
    Error curError = Errors::Failure;

    if (pInSubject && pInObserver) {
        // Lock out updates while we register a subjext
        SCOPED_SPIN_LOCK(m_swUpdate);
        u32 uID = pInSubject->getObserverId(this);

        if (uID != ISubject::InvalidObserverID) {
            // Subject has already been registered. Add new observer to the list
            SubjectInfo& si = m_subjectsList[uID];
            si.m_observersList.push_back(ObserverRequest(pInObserver, observerIntrestBits, observerIdBits));
            observerIntrestBits &= ~si.m_interestBits;

            if (observerIntrestBits) {
                si.m_interestBits |= observerIntrestBits;
                pInSubject->UpdateInterestBits(this, observerIntrestBits);
            }
        } else {
            // New subject
            if (m_freeIDsList.empty()) {
                // No zero ID should ever be assigned, so use pre-increment
                uID = ++m_lastID;
                ASSERT(uID == m_subjectsList.size());
                m_subjectsList.resize(uID + 1);
            } else {
                uID = m_freeIDsList.back();
                m_freeIDsList.pop_back();
            }

            SubjectInfo& si = m_subjectsList[uID];
            si.m_pSubject = pInSubject;
            si.m_observersList.push_back(ObserverRequest(pInObserver, observerIntrestBits, observerIdBits));
            si.m_interestBits = observerIntrestBits;
            pInSubject->Attach(this, observerIntrestBits, uID);
        }

        curError = Errors::Success;
    }

    return curError;
}
示例#3
0
///////////////////////////////////////////////////////////////////////////////
// Register - Register a new subject/observer relationsship
Error ChangeManager::Register(ISystemObject* pInSubject, IObserver* pInObserver) {
    BOOST_ASSERT_MSG(pInSubject != nullptr, "Subject cannot be null");
    BOOST_ASSERT_MSG(pInObserver != nullptr, "Observer cannot be null");

    auto observerIntrestBits = pInObserver->GetDesiredSystemChanges();
    if (pInSubject->GetPotentialSystemChanges() & observerIntrestBits) {
        // Lock out updates while we register a subject
        tbb::spin_mutex::scoped_lock _lock(m_swUpdate);
        unsigned int uID = pInSubject->getObserverId(this);

        if (uID != ISystemObject::InvalidObserverID) {
            // Subject has already been registered. Add new observer to the list
            SubjectInfo &si = m_subjectsList[uID];
            si.m_observersList.push_back(ObserverRequest(pInObserver, uID, observerIntrestBits));
            observerIntrestBits &= ~si.m_interestBits;

            if (observerIntrestBits) {
                si.m_interestBits |= observerIntrestBits;
                pInSubject->UpdateInterestBits(this, observerIntrestBits);
            }
        } else {
            // New subject
            if (m_freeIDsList.empty()) {
                // No zero ID should ever be assigned, so use pre-increment
                uID = ++m_lastID;
                BOOST_ASSERT(uID == m_subjectsList.size());
                m_subjectsList.resize(uID + 1);
            } else {
                uID = m_freeIDsList.back();
                m_freeIDsList.pop_back();
            }

            SubjectInfo &si = m_subjectsList[uID];
            si.m_pSubject = pInSubject;
            si.m_observersList.push_back(ObserverRequest(pInObserver, uID, observerIntrestBits));
            si.m_interestBits = observerIntrestBits;
            pInSubject->Attach(this, observerIntrestBits, uID);
        }
    }

    return Errors::Success;
}