/* * notifier_ext.h * * Smart Notifiers and Notifier Lists * * Portable Windows Library * * Copyright (c) 2004 Reitek S.p.A. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Post Increment * * Contributor(s): ______________________________________. * * $Log: notifier_ext.h,v $ * Revision 1.5 2005/11/30 12:47:37 csoutheren * Removed tabs, reformatted some code, and changed tags for Doxygen * * Revision 1.4 2004/05/17 11:02:39 csoutheren * Added extra documentation * * Revision 1.3 2004/05/09 07:23:48 rjongbloed * More work on XMPP, thanks Federico Pinna and Reitek S.p.A. * * Revision 1.2 2004/04/26 01:34:58 rjongbloed * Change nofier list to be able to used in containers, thanks Federico Pinna, Reitek S.p.A. * * Revision 1.1 2004/04/22 12:31:00 rjongbloed * Added PNotifier extensions and XMPP (Jabber) support, * thanks to Federico Pinna and Reitek S.p.A. * * */ #ifndef _PNOTIFIER_EXT #define _PNOTIFIER_EXT #ifdef P_USE_PRAGMA #pragma interface #endif /** Implements a function similar to the PNotifier, but uses an "id" to link the caller * and callee rather than using a pointer. This has the advantage that if the pointer * becomes invalid, the caller can gracefully fail the notification rather than * simply crashing due to an invalid pointer access. * * These classes were created to support of the XMPP classes */ class PSmartNotifieeRegistrar { public: PSmartNotifieeRegistrar() : m_ID(P_MAX_INDEX) {} ~PSmartNotifieeRegistrar() { UnregisterNotifiee(m_ID); } void Init(void * obj) { if (m_ID == P_MAX_INDEX) m_ID = RegisterNotifiee(obj); } unsigned GetID() const { return m_ID; } static unsigned RegisterNotifiee(void * obj); static BOOL UnregisterNotifiee(unsigned id); static BOOL UnregisterNotifiee(void * obj); static void * GetNotifiee(unsigned id); protected: unsigned m_ID; }; class PSmartNotifierFunction : public PNotifierFunction { PCLASSINFO(PSmartNotifierFunction, PNotifierFunction); protected: unsigned m_NotifieeID; public: PSmartNotifierFunction(unsigned id) : PNotifierFunction(&id), m_NotifieeID(id) { } unsigned GetNotifieeID() const { return m_NotifieeID; } void * GetNotifiee() const { return PSmartNotifieeRegistrar::GetNotifiee(m_NotifieeID); } BOOL IsValid() const { return GetNotifiee() != 0; } }; #define PDECLARE_SMART_NOTIFIEE \ PSmartNotifieeRegistrar m_Registrar; \ #define PCREATE_SMART_NOTIFIEE m_Registrar.Init(this) #define PDECLARE_SMART_NOTIFIER(notifier, notifiee, func) \ class func##_PSmartNotifier : public PSmartNotifierFunction { \ public: \ func##_PSmartNotifier(unsigned id) : PSmartNotifierFunction(id) { } \ virtual void Call(PObject & note, INT extra) const \ { \ void * obj = GetNotifiee(); \ if (obj) \ ((notifiee*)obj)->func((notifier &)note, extra); \ else \ PTRACE(2, "Invalid notifiee"); \ } \ }; \ friend class func##_PSmartNotifier; \ virtual void func(notifier & note, INT extra) #define PCREATE_SMART_NOTIFIER(func) PNotifier(new func##_PSmartNotifier(m_Registrar.GetID())) class PNotifierList : public PObject { PCLASSINFO(PNotifierList, PObject); private: PLIST(_PNotifierList, PNotifier); _PNotifierList m_TheList; // Removes smart pointers to deleted objects void Cleanup(); public: PINDEX GetSize() const { return m_TheList.GetSize(); } void Add(PNotifier * handler) { m_TheList.Append(handler); } void Remove(PNotifier * handler) { m_TheList.Remove(handler); } BOOL RemoveTarget(PObject * obj); BOOL Fire(PObject& obj, INT val = 0); // Moves all the notifiers in "that" to "this" void Move(PNotifierList& that); }; #endif // _PNOTIFIER_EXT // End of File ///////////////////////////////////////////////////////////////