Event.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006-2011, SRI International (R)
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as published by
00006  * the Free Software Foundation, either version 3 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #pragma once
00019 
00020 #ifndef __OpenKarto_Event_h__
00021 #define __OpenKarto_Event_h__
00022 
00023 #include <OpenKarto/List.h>
00024 #include <OpenKarto/Mutex.h>
00025 
00026 // Forward declaration for tbb::mutex
00027 namespace tbb
00028 {
00029   class mutex;
00030 }
00031 
00032 namespace karto
00033 {
00034 
00038 
00039   // The following code is from the Poco library with the following license 
00040   // and modified to fit into the KartoSDK
00041 
00042   // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
00043   // and Contributors.
00044   //
00045   // Permission is hereby granted, free of charge, to any person or organization
00046   // obtaining a copy of the software and accompanying documentation covered by
00047   // this license (the "Software") to use, reproduce, display, distribute,
00048   // execute, and transmit the Software, and to prepare derivative works of the
00049   // Software, and to permit third-parties to whom the Software is furnished to
00050   // do so, all subject to the following:
00051   // 
00052   // The copyright notices in the Software and this entire statement, including
00053   // the above license grant, this restriction and the following disclaimer,
00054   // must be included in all copies of the Software, in whole or in part, and
00055   // all derivative works of the Software, unless such copies or derivative
00056   // works are solely in the form of machine-executable object code generated by
00057   // a source language processor.
00058   // 
00059   // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00060   // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00061   // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
00062   // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
00063   // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
00064   // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00065   // DEALINGS IN THE SOFTWARE.
00066 
00070 
00072 
00073 
00074   //@cond EXCLUDE
00075 
00082   template <class TArgs> 
00083   class AbstractDelegate
00084   {
00085   public:
00090     AbstractDelegate(void* pTarget)
00091       : m_pTarget(pTarget)
00092     {
00093       assert(m_pTarget != 0);
00094     }
00095 
00100     AbstractDelegate(const AbstractDelegate& rOther)
00101       : m_pTarget(rOther.m_pTarget)
00102     {
00103       assert(m_pTarget != 0);
00104     }
00105 
00109     virtual ~AbstractDelegate() 
00110     {
00111     }
00112 
00113   public:
00119     virtual void Notify(const void* pSender, TArgs& rArguments) = 0;
00120 
00125     virtual AbstractDelegate* Clone() const = 0;
00126 
00130     void* GetTarget() const
00131     {
00132       return m_pTarget;
00133     }
00134 
00135   public:
00141     kt_bool operator==(const AbstractDelegate<TArgs>& rOther) const
00142     {
00143       return m_pTarget == rOther.m_pTarget;
00144     }
00145 
00151     kt_bool operator<(const AbstractDelegate<TArgs>& rOther) const
00152     {
00153       return m_pTarget < rOther.m_pTarget;
00154     }
00155 
00156   protected:
00160     void* m_pTarget;
00161   };
00162 
00166 
00167   template <class TObj, class TArgs, bool withSender=true> 
00168   class Delegate: public AbstractDelegate<TArgs>
00169   {
00170   public:
00171     typedef void (TObj::*NotifyMethod)(const void*, TArgs&);
00172 
00173     Delegate(TObj* pObject, NotifyMethod method)
00174       : AbstractDelegate<TArgs>(pObject)
00175       , m_ReceiverObject(pObject)
00176       , m_ReceiverMethod(method)
00177     {
00178     }
00179 
00183     Delegate(const Delegate& rDelegate)
00184       : AbstractDelegate<TArgs>(rDelegate)
00185       , m_ReceiverObject(rDelegate.m_ReceiverObject)
00186       , m_ReceiverMethod(rDelegate.m_ReceiverMethod)
00187     {
00188     }
00189 
00193     virtual ~Delegate()
00194     {
00195     }
00196 
00197   public:
00198     void Notify(const void* pSender, TArgs& rArguments)
00199     {
00200       (m_ReceiverObject->*m_ReceiverMethod)(pSender, rArguments);
00201     }
00202 
00203     AbstractDelegate<TArgs>* Clone() const
00204     {
00205       return new Delegate(*this);
00206     }
00207 
00208   public:
00214     Delegate& operator=(const Delegate& rOther)
00215     {
00216       if (&rOther != this)
00217       {
00218         this->m_pTarget        = rOther.m_pTarget;
00219         this->m_ReceiverObject = rOther.m_ReceiverObject;
00220         this->m_ReceiverMethod = rOther.m_ReceiverMethod;
00221       }
00222       return *this;
00223     }
00224 
00225   protected:
00226     TObj*        m_ReceiverObject;
00227     NotifyMethod m_ReceiverMethod;
00228 
00229   private:
00230     Delegate();
00231   };
00232 
00236 
00237   template <class TObj, class TArgs> 
00238   class Delegate<TObj, TArgs, false>: public AbstractDelegate<TArgs>
00239   {
00240   public:
00241     typedef void (TObj::*NotifyMethod)(TArgs&);
00242 
00243     Delegate(TObj* pObject, NotifyMethod method)
00244       : AbstractDelegate<TArgs>(pObject)
00245       , m_ReceiverObject(pObject)
00246       , m_ReceiverMethod(method)
00247     {
00248     }
00249 
00253     Delegate(const Delegate& rDelegate)
00254       : AbstractDelegate<TArgs>(rDelegate)
00255       , m_ReceiverObject(rDelegate.m_ReceiverObject)
00256       , m_ReceiverMethod(rDelegate.m_ReceiverMethod)
00257     {
00258     }
00259 
00263     virtual ~Delegate()
00264     {
00265     }
00266 
00267   public:
00268     void Notify(const void*, TArgs& rArguments)
00269     {
00270       (m_ReceiverObject->*m_ReceiverMethod)(rArguments);
00271     }
00272 
00273     AbstractDelegate<TArgs>* Clone() const
00274     {
00275       return new Delegate(*this);
00276     }
00277 
00278   public:
00284     Delegate& operator=(const Delegate& rOther)
00285     {
00286       if (&rOther != this)
00287       {
00288         this->m_pTarget        = rOther.m_pTarget;
00289         this->m_ReceiverObject = rOther.m_ReceiverObject;
00290         this->m_ReceiverMethod = rOther.m_ReceiverMethod;
00291       }
00292 
00293       return *this;
00294     }
00295 
00296   protected:
00297     TObj*        m_ReceiverObject;
00298     NotifyMethod m_ReceiverMethod;
00299 
00300   private:
00301     Delegate();
00302   };
00303 
00307 
00312   template <class TArgs, bool hasSender = true, bool senderIsConst = true> 
00313   class FunctionDelegate: public AbstractDelegate<TArgs>
00314   {
00315   public:
00319     typedef void (*NotifyMethod)(const void*, TArgs&);
00320 
00325     FunctionDelegate(NotifyMethod method)
00326       : AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method))
00327       , m_ReceiverMethod(method)
00328     {
00329     }
00330 
00335     FunctionDelegate(const FunctionDelegate& rOther)
00336       : AbstractDelegate<TArgs>(rOther)
00337       , m_ReceiverMethod(rOther.m_ReceiverMethod)
00338     {
00339     }
00340 
00344     virtual ~FunctionDelegate()
00345     {
00346     }
00347 
00348   public:
00349     void Notify(const void* pSender, TArgs& rArguments)
00350     {
00351       (*m_ReceiverMethod)(pSender, rArguments);
00352     }
00353 
00354     AbstractDelegate<TArgs>* Clone() const
00355     {
00356       return new FunctionDelegate(*this);
00357     }
00358 
00359   public:
00365     FunctionDelegate& operator=(const FunctionDelegate& rOther)
00366     {
00367       if (&rOther != this)
00368       {
00369         this->m_pTarget        = rOther.m_pTarget;
00370         this->m_ReceiverMethod = rOther.m_ReceiverMethod;
00371       }
00372       return *this;
00373     }
00374 
00375   protected:
00379     NotifyMethod m_ReceiverMethod;
00380 
00381   private:
00382     FunctionDelegate();
00383   };
00384 
00388 
00393   template <class TArgs> 
00394   class FunctionDelegate<TArgs, true, false>: public AbstractDelegate<TArgs>
00395   {
00396   public:
00400     typedef void (*NotifyMethod)(void*, TArgs&);
00401 
00406     FunctionDelegate(NotifyMethod method)
00407       : AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method))
00408       , m_ReceiverMethod(method)
00409     {
00410     }
00411 
00416     FunctionDelegate(const FunctionDelegate& rOther)
00417       : AbstractDelegate<TArgs>(rOther)
00418       , m_ReceiverMethod(rOther.m_ReceiverMethod)
00419     {
00420     }
00421 
00425     virtual ~FunctionDelegate()
00426     {
00427     }
00428 
00429   public:
00430     void Notify(const void* pSender, TArgs& rArguments)
00431     {
00432       (*m_ReceiverMethod)(const_cast<void*>(pSender), rArguments);
00433     }
00434 
00435     AbstractDelegate<TArgs>* Clone() const
00436     {
00437       return new FunctionDelegate(*this);
00438     }
00439 
00440   public:
00446     FunctionDelegate& operator=(const FunctionDelegate& rOther)
00447     {
00448       if (&rOther != this)
00449       {
00450         this->m_pTarget        = rOther.m_pTarget;
00451         this->m_ReceiverMethod = rOther.m_ReceiverMethod;
00452       }
00453       return *this;
00454     }
00455 
00456   protected:
00460     NotifyMethod m_ReceiverMethod;
00461 
00462   private:
00463     FunctionDelegate();
00464   };
00465 
00469 
00474   template <class TArgs, bool senderIsConst> 
00475   class FunctionDelegate<TArgs, false, senderIsConst>: public AbstractDelegate<TArgs>
00476   {
00477   public:
00481     typedef void (*NotifyMethod)(TArgs&);
00482 
00487     FunctionDelegate(NotifyMethod method)
00488       : AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method))
00489       , m_ReceiverMethod(method)
00490     {
00491     }
00492 
00497     FunctionDelegate(const FunctionDelegate& rOther)
00498       : AbstractDelegate<TArgs>(rOther)
00499       , m_ReceiverMethod(rOther.m_ReceiverMethod)
00500     {
00501     }
00502 
00506     virtual ~FunctionDelegate()
00507     {
00508     }
00509 
00510   public:
00511     void Notify(const void* /*pSender*/, TArgs& rArguments)
00512     {
00513       (*m_ReceiverMethod)(rArguments);
00514     }
00515 
00516     AbstractDelegate<TArgs>* Clone() const
00517     {
00518       return new FunctionDelegate(*this);
00519     }
00520 
00521   public:
00527     FunctionDelegate& operator=(const FunctionDelegate& rOther)
00528     {
00529       if (&rOther != this)
00530       {
00531         this->m_pTarget        = rOther.m_pTarget;
00532         this->m_ReceiverMethod = rOther.m_ReceiverMethod;
00533       }
00534       return *this;
00535     }
00536 
00537   protected:
00541     NotifyMethod m_ReceiverMethod;
00542 
00543   private:
00544     FunctionDelegate();
00545   };
00546 
00550 
00558   template <class TArgs> 
00559   class NotificationStrategy
00560   {
00561   public:
00565     NotificationStrategy()
00566     {
00567     }
00568 
00572     virtual ~NotificationStrategy()
00573     {
00574     }
00575 
00576   public:
00580     virtual void Notify(const void* sender, TArgs& arguments) = 0;
00581 
00585     virtual void Add(const AbstractDelegate<TArgs>& pDelegate) = 0;
00586 
00590     virtual void Remove(const AbstractDelegate<TArgs>& pDelegate) = 0;
00591 
00595     virtual void Clear() = 0;
00596 
00600     virtual bool IsEmpty() const = 0;
00601   };
00602 
00606 
00612   template <class TArgs> 
00613   class DefaultStrategy : public NotificationStrategy<TArgs>
00614   {
00615   public:
00619     typedef karto::List< AbstractDelegate<TArgs>* > DelegateList;
00620 
00621   public:
00625     DefaultStrategy()
00626     {
00627     }
00628 
00633     DefaultStrategy(const DefaultStrategy& rOther)
00634     {
00635       operator = (rOther);
00636     }
00637 
00641     virtual ~DefaultStrategy()
00642     {
00643       Clear();
00644     }
00645 
00646   public:
00647     void Notify(const void* pSender, TArgs& rArguments)
00648     {
00649       karto_forEach(typename DelegateList, &m_Observers)
00650       {
00651         (*iter)->Notify(pSender, rArguments);
00652       }
00653     }
00654 
00655     void Add(const AbstractDelegate<TArgs>& rDelegate)
00656     {
00657       Remove(rDelegate);
00658 
00659       AbstractDelegate<TArgs>* pDelegate = rDelegate.Clone();
00660       m_Observers.Add(pDelegate);
00661     }
00662 
00663     void Remove(const AbstractDelegate<TArgs>& rDelegate)
00664     {
00665       kt_bool found = false;
00666       kt_int32s index = 0;
00667       karto_forEach(typename DelegateList, &m_Observers)
00668       {
00669         if (*(*iter) == rDelegate)
00670         {
00671           delete *iter;
00672           found = true;
00673           break;
00674         }
00675 
00676         index++;
00677       }
00678 
00679       if (found == true)
00680       {
00681         m_Observers.RemoveAt(index);
00682       }
00683     }
00684 
00685     void Clear()
00686     {
00687       karto_forEach(typename DelegateList, &m_Observers)
00688       {
00689         delete *iter;
00690       }
00691       m_Observers.Clear();
00692     }
00693 
00694     kt_bool IsEmpty() const
00695     {
00696       return m_Observers.IsEmpty();
00697     }
00698 
00699   public:
00703     DefaultStrategy& operator=(const DefaultStrategy& rOther)
00704     {
00705       if (this != &rOther)
00706       {
00707         karto_const_forEach(typename DelegateList, &(rOther.m_Observers))
00708         {
00709           Add(**iter);
00710         }
00711       }
00712       return *this;
00713     }
00714 
00715   protected:
00719     DelegateList m_Observers;
00720   };
00721   
00722   // @endcond
00723 
00727 
00805   template <class TArgs> 
00806   class AbstractEvent
00807   {
00808   public:
00812     AbstractEvent()
00813       : m_Enabled(true)
00814     {
00815     }
00816 
00821     AbstractEvent(const DefaultStrategy<TArgs>& rStrategy)
00822       : m_Enabled(true)
00823       , m_Strategy(rStrategy)
00824     {
00825     }
00826 
00830     virtual ~AbstractEvent()
00831     {
00832     }
00833 
00843     void operator+=(const AbstractDelegate<TArgs>& rDelegate)
00844     {
00845       Mutex::ScopedLock lock(m_Mutex);
00846       m_Strategy.Add(rDelegate);
00847     }
00848 
00855     void operator-=(const AbstractDelegate<TArgs>& rDelegate)
00856     {
00857       Mutex::ScopedLock lock(m_Mutex);
00858       m_Strategy.Remove(rDelegate);
00859     }
00860 
00864     void operator()(const void* pSender, TArgs& args)
00865     {
00866       Notify(pSender, args);
00867     }
00868 
00879     void Notify(const void* pSender, TArgs& rArgs)
00880     {
00881       DefaultStrategy<TArgs>* pStrats = NULL;
00882       kt_bool enabled = false;
00883 
00884       {
00885         Mutex::ScopedLock lock(m_Mutex);
00886         enabled = m_Enabled;
00887 
00888         if (m_Enabled)
00889         {
00890           // thread-safeness: 
00891           // copy should be faster and safer than blocking until execution ends
00892           pStrats = new DefaultStrategy<TArgs>(m_Strategy);
00893         }
00894       }
00895 
00896       if (enabled)
00897       {
00898         pStrats->Notify(pSender, rArgs);
00899       }
00900 
00901       delete pStrats;
00902     }
00903 
00907     void Enable()
00908     {
00909       Mutex::ScopedLock lock(m_Mutex);
00910       m_Enabled = true;
00911     }
00912 
00917     void Disable()
00918     {
00919       Mutex::ScopedLock lock(m_Mutex);
00920       m_Enabled = false;
00921     }
00922 
00926     kt_bool IsEnabled() const
00927     {
00928       Mutex::ScopedLock lock(m_Mutex);
00929       return m_Enabled;
00930     }
00931 
00935     void Clear()
00936     {
00937       Mutex::ScopedLock lock(m_Mutex);
00938       m_Strategy.Clear();
00939     }
00940 
00944     kt_bool IsEmpty() const
00945     {
00946       Mutex::ScopedLock lock(m_Mutex);
00947       return m_Strategy.IsEmpty();
00948     }
00949 
00950   protected:
00954     kt_bool m_Enabled; 
00955 
00959     DefaultStrategy<TArgs> m_Strategy; 
00960 
00964     mutable Mutex m_Mutex;
00965 
00966   private:
00967     AbstractEvent(const AbstractEvent& rOther);
00968     AbstractEvent& operator=(const AbstractEvent& rOther);
00969   };
00970 
00974   
00989   template <class TArgs> 
00990   class BasicEvent : public AbstractEvent <TArgs >
00991   {
00992   public:
00993     BasicEvent()
00994     {
00995     }
00996 
00997     virtual ~BasicEvent()
00998     {
00999     }
01000 
01001   private:
01002     BasicEvent(const BasicEvent& e);
01003     BasicEvent& operator=(const BasicEvent& e);
01004   };
01005 
01009 
01017   class KARTO_EXPORT EventArguments
01018   {
01019   public:
01020     EventArguments();
01021     virtual ~EventArguments();
01022 
01023   public:
01028     static EventArguments& Empty()
01029     {
01030       static EventArguments dummy;
01031 
01032       return dummy;
01033     }
01034   }; // class EventArguments
01035 
01036 #ifdef WIN32
01037 #define EXPORT_KARTO_EVENT(declspec, T) \
01038   template class declspec karto::BasicEvent<T>;
01039 
01040   EXPORT_KARTO_EVENT(KARTO_EXPORT, EventArguments)
01041 #endif
01042 
01046 
01047   template <class TObj, class TArgs>
01048   static Delegate<TObj, TArgs, true> delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&))
01049   {
01050     return Delegate<TObj, TArgs, true>(pObj, NotifyMethod);
01051   }
01052 
01053   template <class TObj, class TArgs>
01054   static Delegate<TObj, TArgs, false> delegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&))
01055   {
01056     return Delegate<TObj, TArgs, false>(pObj, NotifyMethod);
01057   }
01058 
01059   template <class TArgs>
01060   static FunctionDelegate<TArgs, true, true> delegate(void (*NotifyMethod)(const void*, TArgs&))
01061   {
01062     return FunctionDelegate<TArgs, true, true>(NotifyMethod);
01063   }
01064 
01065   template <class TArgs>
01066   static FunctionDelegate<TArgs, true, false> delegate(void (*NotifyMethod)(void*, TArgs&))
01067   {
01068     return FunctionDelegate<TArgs, true, false>(NotifyMethod);
01069   }
01070 
01071   template <class TArgs>
01072   static FunctionDelegate<TArgs, false> delegate(void (*NotifyMethod)(TArgs&))
01073   {
01074     return FunctionDelegate<TArgs, false>(NotifyMethod);
01075   }
01076 
01078 
01079 }
01080 
01081 #endif // __OpenKarto_Event_h__


nav2d_karto
Author(s): Sebastian Kasperski
autogenerated on Sun Apr 2 2017 03:53:08