EventLinksGroup.h

См. документацию.
00001 /*
00002  * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события
00003  * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru
00004  * _______________________________________________________________________________
00005  * Разрешено свободное использование, копирование, распространение, изменение
00006  * (изменение сведений об авторских правах запрещено). Запрещена продажа и 
00007  * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об
00008  * авторских правах на программу (или сведениях о программе, об авторах, 
00009  * использованных средствах разработки и т.д.) должна быть указана информация
00010  * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е.
00011  * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора.
00012  */ 
00013 
00014 #ifndef CNTM_EVENTLINKSGROUP_H
00015 #define CNTM_EVENTLINKSGROUP_H
00016 #include <boost/utility.hpp>
00017 #include <boost/thread/recursive_mutex.hpp>
00018 #include <Cntm/Utils/SignatureInfo.h>
00019 #include <Cntm/RefCount/RefPtr.h>
00020 #include <Cntm/Synchro/SynchroSpace.h>
00021 #include <Cntm/Events/DeferEvent.h>
00022 #include <Cntm/Events/DirectEvent.h>
00023 
00024 namespace Cntm
00025 {
00026 
00027         /**
00028          * Класс группы связей между событием и обработчиком. В качестве события используется либо отложенное либо прямое событие (см. классы Cntm::DeferEvent и Cntm::DirectEvent). Выполняет теже функции, что и обычная связь (см. класс Cntm::EventLink), но может хранить сразу несколько связей. Операция Attach() добавляет новую связь к группе, при этом старые связи сохраняются. Операция Detach() влияет на всю группу, она уничтожает все связи, присутствующие на данный момент в группе.
00029          * 
00030          * Данный класс имеет конструктор по умолчанию, создающий пустую связь и конструкторы инициализации, создающие связь указанного события с указанным обработчиком. В деструкторе класса происходит разрушение всех связей, хранящихся в группе. Методы Attach() добавляет новую связь. Метод Detach() разрушает все связи, хранящиеся в группе. Данный класс не имеет конструктора и оператора копирования.
00031          * 
00032          * Данный класс является общим для отложенных и прямых событий, и не является шаблоном, т.е. не зависит от сигнатуры события.
00033          * 
00034          * Более подробное описание использование класса приведено в описании классов событий (см. классы Cntm::DeferEvent и Cntm::DirectEvent).
00035          * 
00036          * Данный класс обеспечивает многопоточность.
00037          * @author Овсеевич Р.
00038          * \ingroup Events
00039          */
00040         class EventLinksGroup: boost::noncopyable
00041         {
00042         public:
00043         
00044                 /**
00045                  * Конструктор по умолчанию. Создает пустую связь. 
00046                  */
00047                 EventLinksGroup() {}
00048                 
00049                 /**
00050                  * Конструктор инициализации связи. В качестве параметров указывается объект отложенного события, ссылочный указатель на объект обработчика, указатель на метод обработчика, ссылочный указатель на синхропространство (опционально).
00051                  * 
00052                  * Исключения:
00053                  * Cntm::NullArgException - если указатель на объект обработчика равен NULL;
00054                  * Cntm::IllegalStateException - если не удалось определить синхропространство в котором будет вызван обработчик (явно не задано и не создано главное синхропространство).
00055                  * @param Event - ссылка на объект отложенного события, т.е. должен передаваться объект события, с которым происходит связывание. 
00056                  * @param Object - ссылочный указатель на объект, который будет обрабатывать событие. Если указатель равен NULL, то генерируется исключение Cntm::NullArgException.
00057                  * @param Method - указатель на метод обработчика. Сигнатура метода должна полностью совпадать с сигнатурой события, в противном случае будет выдана ошибка компиляции.
00058                  * @param Space (опциональный) - синхропространство, в котором будет выполняться обработчик. Если оно явно не указано, то определяется следующим образом. Если объект обработчика является синхрообъектом (см. класс Cntm::SynchroObject), то синхропространство берется из свойства Space() этого объекта. В противном случае используется главное синхропространство (см. Cntm::SynchroSpace::Main()). Если главного синхропространства нет (Cntm::SynchroSpace::Main() возвращает NULL), то генерируется исключение Cntm::IllegalStateException.
00059                  */
00060                 template < typename SignatureT, typename ClassT >
00061                 EventLinksGroup(DeferEvent < SignatureT > & Event, 
00062                         RefPtr < ClassT > Object, 
00063                         typename SignatureInfo < SignatureT > ::template Method < ClassT > ::Pointer Method, 
00064                         const SynchroSpace::Ptr& Space = SynchroSpace::Ptr())
00065                 {
00066                         first = new HandlerStorage(Event.GetHandlersRegister(Object.Pointer(), Space), 
00067                                 HandlerType(Object, reinterpret_cast<typename HandlerType::SignInfo::template Method<ClassT>::Pointer>(Method)));
00068                 }
00069                         
00070                 /**
00071                  * Конструктор инициализации связи. В качестве параметров указывается объект отложенного события, обычный указатель на объект обработчика, указатель на метод обработчика, ссылочный указатель на синхропространство (опционально).
00072                  * 
00073                  * Исключения:
00074                  * Cntm::NullArgException - если указатель на объект обработчика равен NULL;
00075                  * Cntm::IllegalStateException - если не удалось определить синхропространство в котором будет вызван обработчик (явно не задано и не создано главное синхропространство).
00076                  * @param Event - ссылка на объект отложенного события, т.е. должен передаваться объект события, с которым происходит связывание. 
00077                  * @param Object - обычный указатель на объект, который будет обрабатывать событие. Если указатель равен NULL, то генерируется исключение Cntm::NullArgException.
00078                  * @param Method - указатель на метод обработчика. Сигнатура метода должна полностью совпадать с сигнатурой события, в противном случае будет выдана ошибка компиляции.
00079                  * @param Space (опциональный) - синхропространство, в котором будет выполняться обработчик. Если оно явно не указано, то определяется следующим образом. Если объект обработчика является синхрообъектом (см. класс Cntm::SynchroObject), то синхропространство берется из свойства Space() этого объекта. В противном случае используется главное синхропространство (см. Cntm::SynchroSpace::Main()). Если главного синхропространства нет (Cntm::SynchroSpace::Main() возвращает NULL), то генерируется исключение Cntm::IllegalStateException.
00080                  */
00081                 template < typename SignatureT, typename ClassT >
00082                 EventLinksGroup(DeferEvent < SignatureT > & Event, 
00083                         ClassT* Object,
00084                         typename SignatureInfo < SignatureT > ::template Method < ClassT > ::Pointer Method, 
00085                         const SynchroSpace::Ptr& Space = SynchroSpace::Ptr())
00086                 {
00087                         first = new HandlerStorage(Event.GetHandlersRegister(Object, Space), 
00088                                 HandlerType(Object, reinterpret_cast<typename HandlerType::SignInfo::template Method<ClassT>::Pointer>(Method)));
00089                 }
00090                         
00091                 /**
00092                  * Конструктор инициализации связи. В качестве параметров указывается объект прямого события, ссылочный указатель на объект обработчика, указатель на метод обработчика.
00093                  * 
00094                  * Исключение Cntm::NullArgException - если указатель на объект обработчика равен NULL.
00095                  * @param Event - ссылка на объект прямого события, т.е. должен передаваться объект события, с которым происходит связывание. 
00096                  * @param Object - ссылочный указатель на объект, который будет обрабатывать событие. Если указатель равен NULL, то генерируется исключение Cntm::NullArgException.
00097                  * @param Method - указатель на метод обработчика. Сигнатура метода должна полностью совпадать с сигнатурой события, в противном случае будет выдана ошибка компиляции.
00098                  */
00099                 template < typename SignatureT, typename ClassT >
00100                 EventLinksGroup(DirectEvent < SignatureT > & Event, 
00101                         RefPtr < ClassT > Object, 
00102                         typename SignatureInfo < SignatureT > ::template Method < ClassT > ::Pointer Method)
00103                 {
00104                         first = new HandlerStorage(Event.GetHandlersRegister(Object.Pointer()), 
00105                                 HandlerType(Object, reinterpret_cast<typename HandlerType::SignInfo::template Method<ClassT>::Pointer>(Method)));
00106                 }
00107                         
00108                 /**
00109                  * Конструктор инициализации связи. В качестве параметров указывается объект прямого события, обычный указатель на объект обработчика, указатель на метод обработчика.
00110                  * 
00111                  * Исключения:
00112                  * Cntm::NullArgException - если указатель на объект обработчика равен NULL;
00113                  * @param Event - ссылка на объект прямого события, т.е. должен передаваться объект события, с которым происходит связывание. 
00114                  * @param Object - обычный указатель на объект, который будет обрабатывать событие. Если указатель равен NULL, то генерируется исключение Cntm::NullArgException.
00115                  * @param Method - указатель на метод обработчика. Сигнатура метода должна полностью совпадать с сигнатурой события, в противном случае будет выдана ошибка компиляции.
00116                  */
00117                 template < typename SignatureT, typename ClassT >
00118                 EventLinksGroup(DirectEvent < SignatureT > & Event, 
00119                         ClassT* Object,
00120                         typename SignatureInfo < SignatureT > ::template Method < ClassT > ::Pointer Method)
00121                 {
00122                         first = new HandlerStorage(Event.GetHandlersRegister(Object), 
00123                                 HandlerType(Object, reinterpret_cast<typename HandlerType::SignInfo::template Method<ClassT>::Pointer>(Method)));
00124                 }
00125                         
00126                 /**
00127                  * Добавление новой связи к группе. В качестве параметров указывается объект отложенного события, ссылочный указатель на объект обработчика, указатель на метод обработчика, ссылочный указатель на синхропространство (опционально).
00128                  * 
00129                  * Исключения:
00130                  * Cntm::NullArgException - если указатель на объект обработчика равен NULL;
00131                  * Cntm::IllegalStateException - если не удалось определить синхропространство в котором будет вызван обработчик (явно не задано и не создано главное синхропространство).
00132                  * @param Event - ссылка на объект отложенного события, т.е. должен передаваться объект события, с которым происходит связывание. 
00133                  * @param Object - ссылочный указатель на объект, который будет обрабатывать событие. Если указатель равен NULL, то генерируется исключение Cntm::NullArgException.
00134                  * @param Method - указатель на метод обработчика. Сигнатура метода должна полностью совпадать с сигнатурой события, в противном случае будет выдана ошибка компиляции.
00135                  * @param Space (опциональный) - синхропространство, в котором будет выполняться обработчик. Если оно явно не указано, то определяется следующим образом. Если объект обработчика является синхрообъектом (см. класс Cntm::SynchroObject), то синхропространство берется из свойства Space() этого объекта. В противном случае используется главное синхропространство (см. Cntm::SynchroSpace::Main()). Если главного синхропространства нет (Cntm::SynchroSpace::Main() возвращает NULL), то генерируется исключение Cntm::IllegalStateException.
00136                  */
00137                 template < typename SignatureT, typename ClassT >
00138                 void Attach(DeferEvent < SignatureT > & Event, 
00139                         RefPtr < ClassT > Object, 
00140                         typename SignatureInfo < SignatureT > ::template Method < ClassT > ::Pointer Method, 
00141                         const SynchroSpace::Ptr& Space = SynchroSpace::Ptr())
00142                 {
00143                         HandlerStorage* hs = new HandlerStorage(Event.GetHandlersRegister(Object.Pointer(), Space), 
00144                                 HandlerType(Object, reinterpret_cast<typename HandlerType::SignInfo::template Method<ClassT>::Pointer>(Method)));
00145                         boost::recursive_mutex::scoped_lock lock(mutex);
00146                         hs->SetNextHandler(first);
00147                         first = hs;                     
00148                 }
00149                         
00150                 /**
00151                  * Добавление новой связи к группе. В качестве параметров указывается объект отложенного события, обычный указатель на объект обработчика, указатель на метод обработчика, ссылочный указатель на синхропространство (опционально).
00152                  * 
00153                  * Исключения:
00154                  * Cntm::NullArgException - если указатель на объект обработчика равен NULL;
00155                  * Cntm::IllegalStateException - если не удалось определить синхропространство в котором будет вызван обработчик (явно не задано и не создано главное синхропространство).
00156                  * @param Event - ссылка на объект отложенного события, т.е. должен передаваться объект события, с которым происходит связывание. 
00157                  * @param Object - обычный указатель на объект, который будет обрабатывать событие. Если указатель равен NULL, то генерируется исключение Cntm::NullArgException.
00158                  * @param Method - указатель на метод обработчика. Сигнатура метода должна полностью совпадать с сигнатурой события, в противном случае будет выдана ошибка компиляции.
00159                  * @param Space (опциональный) - синхропространство, в котором будет выполняться обработчик. Если оно явно не указано, то определяется следующим образом. Если объект обработчика является синхрообъектом (см. класс Cntm::SynchroObject), то синхропространство берется из свойства Space() этого объекта. В противном случае используется главное синхропространство (см. Cntm::SynchroSpace::Main()). Если главного синхропространства нет (Cntm::SynchroSpace::Main() возвращает NULL), то генерируется исключение Cntm::IllegalStateException.
00160                  */
00161                 template < typename SignatureT, typename ClassT >
00162                 void Attach(DeferEvent < SignatureT > & Event, 
00163                         ClassT* Object, 
00164                         typename SignatureInfo < SignatureT > ::template Method < ClassT > ::Pointer Method, 
00165                         const SynchroSpace::Ptr& Space = SynchroSpace::Ptr())
00166                 {
00167                         HandlerStorage* hs = new HandlerStorage(Event.GetHandlersRegister(Object, Space), 
00168                                 HandlerType(Object, reinterpret_cast<typename HandlerType::SignInfo::template Method<ClassT>::Pointer>(Method)));
00169                         boost::recursive_mutex::scoped_lock lock(mutex);
00170                         hs->SetNextHandler(first);
00171                         first = hs;                     
00172                 }
00173                 
00174                 /**
00175                  * Добавление новой связи к группе. В качестве параметров указывается объект прямого события, ссылочный указатель на объект обработчика, указатель на метод обработчика.
00176                  * 
00177                  * Исключения:
00178                  * Cntm::NullArgException - если указатель на объект обработчика равен NULL;
00179                  * @param Event - ссылка на объект прямого события, т.е. должен передаваться объект события, с которым происходит связывание. 
00180                  * @param Object - ссылочный указатель на объект, который будет обрабатывать событие. Если указатель равен NULL, то генерируется исключение Cntm::NullArgException.
00181                  * @param Method - указатель на метод обработчика. Сигнатура метода должна полностью совпадать с сигнатурой события, в противном случае будет выдана ошибка компиляции.
00182                  */
00183                 template < typename SignatureT, typename ClassT >
00184                 void Attach(DirectEvent < SignatureT > & Event, 
00185                         RefPtr < ClassT > Object, 
00186                         typename SignatureInfo < SignatureT > ::template Method < ClassT > ::Pointer Method)
00187                 {
00188                         HandlerStorage* hs = new HandlerStorage(Event.GetHandlersRegister(Object.Pointer()), 
00189                                 HandlerType(Object, reinterpret_cast<typename HandlerType::SignInfo::template Method<ClassT>::Pointer>(Method)));
00190                         boost::recursive_mutex::scoped_lock lock(mutex);
00191                         hs->SetNextHandler(first);
00192                         first = hs;                     
00193                 }
00194                         
00195                 /**
00196                  * Добавление новой связи к группе. В качестве параметров указывается объект прямого события, обычный указатель на объект обработчика, указатель на метод обработчика.
00197                  * 
00198                  * Исключения:
00199                  * Cntm::NullArgException - если указатель на объект обработчика равен NULL;
00200                  * @param Event - ссылка на объект прямого события, т.е. должен передаваться объект события, с которым происходит связывание. 
00201                  * @param Object - обычный указатель на объект, который будет обрабатывать событие. Если указатель равен NULL, то генерируется исключение Cntm::NullArgException.
00202                  * @param Method - указатель на метод обработчика. Сигнатура метода должна полностью совпадать с сигнатурой события, в противном случае будет выдана ошибка компиляции.
00203                  */
00204                 template < typename SignatureT, typename ClassT >
00205                 void Attach(DirectEvent < SignatureT > & Event, 
00206                         ClassT* Object, 
00207                         typename SignatureInfo < SignatureT > ::template Method < ClassT > ::Pointer Method)
00208                 {
00209                         HandlerStorage* hs = new HandlerStorage(Event.GetHandlersRegister(Object), 
00210                                 HandlerType(Object, reinterpret_cast<typename HandlerType::SignInfo::template Method<ClassT>::Pointer>(Method)));
00211                         boost::recursive_mutex::scoped_lock lock(mutex);
00212                         hs->SetNextHandler(first);
00213                         first = hs;                     
00214                 }
00215                 
00216                 /**
00217                  * Разрушить все связи, хранящиеся в группе.
00218                  */
00219                 void Detach()
00220                 {
00221                         boost::recursive_mutex::scoped_lock lock(mutex);
00222                         HandlerStorage::Ptr temp = first;
00223                         first.SetNull();
00224                         lock.unlock();
00225                         temp.SetNull();
00226                 }
00227                 
00228         private:
00229         
00230                 typedef SpecUtils::BasicEvent::HandlerType HandlerType;
00231                 typedef SpecUtils::BasicEvent::HandlersRegisterEx HandlersRegister;
00232 
00233                 /**
00234                  * Класс эл-та однонаправленного списка, используемый для хранения связи. Содержит как саму связь, так и ссылочный указатель на следующую связь. 
00235                  */
00236                 class HandlerStorage: public RefBase
00237                 {
00238                 public:
00239                 
00240                         /**
00241                          * Конструктор. 
00242                          */
00243                         HandlerStorage(const HandlersRegister::Ptr& Reg, const HandlerType& Value): handler(Reg, Value) {}
00244 
00245                         /**
00246                          * Установить указатель на следующую связь. 
00247                          */
00248                         void SetNextHandler(const HandlerStorage::Ptr& Next) { next = Next; }
00249                         
00250                 private:
00251                 
00252                         /**
00253                          * Эл-т перечня, содержащий информацию об обработчике события.
00254                          */
00255                         HandlersRegister::Item handler;                 
00256 
00257                         /**
00258                          * Ссылочный указатель на следующую связь. 
00259                          */
00260                         HandlerStorage::Ptr next;
00261                 };
00262 
00263                 /**
00264                  * Глобальная критическая секция для операций с указателем на первую связь, хранящуюся в группе.
00265                  */
00266                 static boost::recursive_mutex mutex;            
00267 
00268                 /**
00269                  * Ссылочный указатель на первую связь, хранящуюся в группе. Когда происходит добавление новой связи, она получает ссылочный указатель на текущую первую связь, а этому указателю присваивается новое значение. Т.о. строится однонаправленный список текущих связей группы. Когда происходит удаление всех связей в методе Detach() или деструкторе, то указатель на первую связь теряется и  начинается цепная реакция уничтожения связей, начиная с последней добавленной. 
00270                  */
00271                 HandlerStorage::Ptr first;
00272         };
00273 
00274 }
00275 
00276 #endif //CNTM_EVENTLINKSGROUP_H

SourceForge.net Logo
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой  doxygen 1.5.3