/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : This file declares templates to be used when a class can // have a list of observers to feed #ifndef CRYINCLUDE_EDITOR_UTIL_OBSERVABLE_H #define CRYINCLUDE_EDITOR_UTIL_OBSERVABLE_H #pragma once #include //! Observable template class, holds a list of observers which can be called at once using the helper defines template class CObservable { public: // Description: // Register a new observer for the class, will check if not already added // Return: // true - if the observer was successfully added to the list // false - if the observer is already in the list bool RegisterObserver(T* pObserver) { if (m_observers.end() != std::find(m_observers.begin(), m_observers.end(), pObserver)) { return false; } m_observers.push_back(pObserver); return true; } // Description: // Unregister an observer from the list // Return: // true - if the observer was successfuly removed // false - if the observer is not in the list bool UnregisterObserver(T* pObserver) { typename std::vector::iterator iter; if (m_observers.end() == (iter = std::find(m_observers.begin(), m_observers.end(), pObserver))) { return false; } m_observers.erase(iter); return true; } // Description: // Uregister all the observers void UnregisterAllObservers() { m_observers.clear(); } protected: std::vector m_observers; }; // // Helper defines to ease the process of calling the methods of all observers in the list // // Description: // Call the method of the observers, this must be used inside the subject class // Example: CALL_OBSERVERS_METHOD(OnStuffHappened(120, "NO!")) #define CALL_OBSERVERS_METHOD(methodCall) \ { for (size_t iObs = 0, iObsCount = m_observers.size(); iObs < iObsCount; ++iObs) { m_observers[iObs]->methodCall; } \ } // Description: // Call the method of the observers, this can be used outside the subject class // Example: CALL_OBSERVERS_METHOD_OF(pSomeObservableSubject, OnStuffHappened(120, "NO!")) #define CALL_OBSERVERS_METHOD_OF(pObservable, methodCall) \ { for (size_t iObs = 0, iObsCount = pObservable->m_observers.size(); iObs < iObsCount; ++iObs) { pObservable->m_observers[iObs]->methodCall; } \ } // Description: // Call the method of the observers, this can be called using a custom vector of observers // Example: CALL_SPECIFIED_OBSERVERS_LIST_METHOD(vMyPreciousSpecialObservers, OnStuffHappened(120, "NO!")) #define CALL_SPECIFIED_OBSERVERS_LIST_METHOD(vObservers, methodCall) \ { for (size_t iObs = 0, iObsCount = vObservers.size(); iObs < iObsCount; ++iObs) { vObservers[iObs]->methodCall; } \ } // Description: // Implement the observable methods when the user class is inheriting from a virtual interface using the observable methods #define IMPLEMENT_OBSERVABLE_METHODS(observerClassName) \ virtual bool RegisterObserver(observerClassName * pObserver) { return CObservable::RegisterObserver(pObserver); }; \ virtual bool UnregisterObserver(observerClassName * pObserver) { return CObservable::UnregisterObserver(pObserver); }; \ virtual void UnregisterAllObservers() { CObservable::UnregisterAllObservers(); }; #endif // CRYINCLUDE_EDITOR_UTIL_OBSERVABLE_H