C++ (Qt)CMeshProgress::SetIndicator("Calculating Normals", mNormals.size());
C++ (Qt) func1(); // <<<<<< Вот после выхода из func1 индикатор определенный в func2 отключиться. // Так не надо было писать? Ну извините, я забыл про это ограничение. :)
C++ (Qt)Statistica st; ... CMeshCalculator calc;calc.reg( new TextProgressIndicatorObserver ); // Регистрируем наблюдателя для вывода прогрессаif( useStatistica ) calc.reg( ?st ); // Если нужно - регистрируем наблюдателя для ведения статистики
C++ (Qt)#ifndef CMESHCALCULATOR_H#define CMESHCALCULATOR_H #include <list> class CMeshCalculator; class IObserver {public: virtual void handleEvent(const CMeshCalculator &) = 0;}; class CMeshCalculator {public: CMeshCalculator() :_someParam(0) {} int someParam() const { return _someParam; } void calculate() { // Possible here _someParam is changed. // for example: _someParam++; notify(); // ... } void reg(IObserver &ref) { _observers.push_back(&ref); } void unreg(IObserver &ref) { _observers.remove(&ref); } private: std::list<IObserver*> _observers; typedef std::list<IObserver*>::iterator _iterator; void notify() { for(_iterator it = _observers.begin(); it != _observers.end(); it++) (*it)->handleEvent(*this); } int _someParam;}; #endif // CMESHCALCULATOR_H
C++ (Qt)#ifndef TEXTPROGRESSINDICATOROBSERVER_H#define TEXTPROGRESSINDICATOROBSERVER_H #include <iostream>#include "CMeshCalculator.h" class TextProgressIndicatorObserver : public IObserver {public: void handleEvent(const CMeshCalculator &calc) { std::cout << "processing..." << std::endl; std::cout << calc.someParam() << std::endl; }}; #endif // TEXTPROGRESSINDICATOROBSERVER_H
C++ (Qt)#include <iostream>#include "CMeshCalculator.h"#include "TextProgressIndicatorObserver.h" using namespace std; int main(){ TextProgressIndicatorObserver tpiObserver; CMeshCalculator calc; calc.reg(tpiObserver); calc.calculate(); return 0;}
C++ (Qt) void handleEvent(const CMeshCalculator &calc)
C++ (Qt)#include <list>#include <cassert> template<typename Subject, typename Observer, void (Observer::*func)( Subject & )>class ObserverSubject{ typedef Observer* Pointer; typedef std::list<Pointer> List; public: void regObserver( Pointer o ) { assert( o ); m_listObservers.push_back( o ); } void unregObserver( Pointer o ) { assert( o ); m_listObservers.remove( o ); } void notifyObserver() { for( typename List::iterator i = m_listObservers.begin(); i != m_listObservers.end(); ++i ) ((*i)->*func)( static_cast<Subject&>( *this ) ); } private: List m_listObservers;};
C++ (Qt)class CMeshCalculator; // Определяем абстрактный базовый класс наблюдателей.// Имя функции может быть любой (указывается в параметрах шаблона)class Observer{public: virtual void update( CMeshCalculator &obj ) = 0;}; // Добавляем к базовым классам ObserverSubject.class CMeshCalculator : public ObserverSubject<CMeshCalculator, Observer, &Observer::update>{public: CMeshCalculator() : m_index( -1 ) {} void func() { for( m_index = 0; m_index < 20; ++m_index ) { // В точках, где необходимо позвать наблюдателей добавляем: notifyObserver(); } } inline int index() const { return m_index; } private: int m_index;}; // Описываем наблюдателя для индикацииclass Indicator : public Observer{public: Indicator( int step = 10 ) : m_step( step ) {} void update( CMeshCalculator &obj ) { if( !(obj.index() % m_step) ) std::cout << "[Indicator] " << " progress: " << obj.index() << std::endl; } private: int m_step;}; // Описываем наблюдателя для ведения логаclass Log : public Observer{public: void update( CMeshCalculator &obj ) { std::cout << "[Log] " << " progress: " << obj.index() << std::endl; }}; int main( int, char ** ){ Indicator i( 5 ); Log l; CMeshCalculator calc; // Регистрируем нужных наблюдателей calc.regObserver( &i ); calc.regObserver( &l ); calc.func(); return 0;}