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_SYNCHROREFHANDLE_H 00015 #define CNTM_SYNCHROREFHANDLE_H 00016 #include <Cntm/RefUtils/Internal/SynchroRefHandleRefImplementation.h> 00017 #include <Cntm/RefUtils/Internal/BasicRefHandle.h> 00018 #include <Cntm/Synchro/SynchroObject.h> 00019 00020 namespace Cntm 00021 { 00022 00023 /** 00024 * Механизм хэндлов предназначен для автоматизации вызова определенного метода объекта при уничтожении последнего хэндла, связанного с объектом. 00025 * 00026 * Данный класс является шаблоном, первым параметром которого является тип объекта, а вторым - указатель на метод объекта, который следует вызвать. Метод должен иметь сигнатуру void(void), т.е. ничего не принимать и не возвращать. 00027 * 00028 * Указанный в шаблоне метод может вызываться многократно. Это происходит, если после уничтожения всех хэндлов, связанных с объектом и вызова указанного метода, вновь будут созданы хэндлы, связанные с объектом. 00029 * 00030 * Отличием данного класса от RefHandle является то, что гарантируется синхронизированный отложенный вызов указанного в шаблоне метода. Это приводит к тому, что объект, с которым связан хэндл, может быть только синхрообъектом. 00031 * 00032 * Особенность вызова указанного в шаблоне метода. Если после того, как будет уничтожен последний хэндл, связанный с объектом, но до выполнения метода (он вызывается отложенно) создать новый хэндл, связанный с объектом, внутри синхропространства, к которому принадлежит объект, то гарантируется, что вызов метода будет отменен. 00033 * 00034 * Пример: 00035 * \code 00036 * class Class1: public SynchroRefBase 00037 * { 00038 * public: 00039 * typedef RefPtr<Class1> Ptr; 00040 * void Close() { cout << "Class1::Close()" << endl; } 00041 * typedef SynchroRefHandle<Class1, &Class1::Close> Handle; 00042 * }; 00043 * 00044 * int main(int argc, char **argv) 00045 * { 00046 * Cntm::QTMainSynchroSpace::Application a(argc, argv); 00047 * 00048 * mw = new Form1(); 00049 * mw->setCaption( "Form1" ); 00050 * mw->show(); 00051 * a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) ); 00052 * 00053 * Class1::Ptr p(new Class1); 00054 * 00055 * if (Какое-то условие) 00056 * { 00057 * Class1::Handle h1 = p; 00058 * Какието-действия с объектом p. 00059 * } // Гарантируется вызов метода Close() для объекта p после уничтожения хэндла, связанного с ним. 00060 * a.exec(); 00061 * } 00062 * \endcode 00063 * 00064 * Класс обеспечивает многопоточность. 00065 * @author Овсеевич Р. 00066 * \ingroup RefUtils 00067 */ 00068 template < typename T, void (T::*FinalizeP)()> 00069 class SynchroRefHandle: public SpecUtils::BasicRefHandle < T, SpecUtils::SynchroRefHandleRefImplementation > 00070 { 00071 public: 00072 00073 /** 00074 * Конструктор по умолчанию. Создает хэндл, не связанный ни с каким объектом. 00075 */ 00076 SynchroRefHandle(): 00077 SpecUtils::BasicRefHandle<T, SpecUtils::SynchroRefHandleRefImplementation>(RefPtr<T>(), &SynchroRefHandle::Finalize) 00078 { 00079 CheckTypeCast<SynchroObject*>((T*)NULL); 00080 } 00081 00082 /** 00083 * Конструктор. Создает хэндл, связанный с указанным объектом. 00084 */ 00085 SynchroRefHandle(RefPtr<T> Object): 00086 SpecUtils::BasicRefHandle<T, SpecUtils::SynchroRefHandleRefImplementation>(Object, &SynchroRefHandle::Finalize) 00087 { 00088 CheckTypeCast<SynchroObject*>((T*)NULL); 00089 } 00090 00091 /** 00092 * Связывает хэндл с новым объектом. 00093 */ 00094 SynchroRefHandle < T, FinalizeP > & operator = (RefPtr<T> Object) 00095 { 00096 Assign(Object); 00097 return *this; 00098 } 00099 00100 /** 00101 * Связывает хэндл с новым объектом. 00102 */ 00103 void Assign(RefPtr<T> Object) 00104 { 00105 SpecUtils::BasicRefHandle<T, SpecUtils::SynchroRefHandleRefImplementation>:: 00106 Assign(Object, &SynchroRefHandle::Finalize); 00107 } 00108 00109 /** 00110 * Делает хэндл не связанным. 00111 */ 00112 void Unassign() 00113 { 00114 Assign(RefPtr<T>::Null()); 00115 } 00116 00117 private: 00118 00119 /** 00120 * Вызывает указанный метод объекта. 00121 */ 00122 static void Finalize(RefPtr<T> HandledObject) { (HandledObject.Pointer()->*FinalizeP)(); } 00123 }; 00124 00125 } 00126 00127 #endif //CNTM_SYNCHROREFHANDLE_H
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |