pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_Sender.h
00001 /*
00002  -------------------------------------------------------------------------------
00003  This file is part of the Plink, Plonk, Plank libraries
00004   by Martin Robinson
00005  
00006  http://code.google.com/p/pl-nk/
00007  
00008  Copyright University of the West of England, Bristol 2011-14
00009  All rights reserved.
00010  
00011  Redistribution and use in source and binary forms, with or without
00012  modification, are permitted provided that the following conditions are met:
00013  
00014  * Redistributions of source code must retain the above copyright
00015    notice, this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright
00017    notice, this list of conditions and the following disclaimer in the
00018    documentation and/or other materials provided with the distribution.
00019  * Neither the name of University of the West of England, Bristol nor 
00020    the names of its contributors may be used to endorse or promote products
00021    derived from this software without specific prior written permission.
00022  
00023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026  DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 
00027  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00028  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00029  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00032  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00033  
00034  This software makes use of third party libraries. For more information see:
00035  doc/license.txt included in the distribution.
00036  -------------------------------------------------------------------------------
00037  */
00038 
00039 #ifndef PLONK_SENDER_H
00040 #define PLONK_SENDER_H
00041 
00042 #include "plonk_CoreForwardDeclarations.h"
00043 #include "plonk_SmartPointer.h"
00044 #include "plonk_WeakPointer.h"
00045 
00046 #include "../containers/plonk_ContainerForwardDeclarations.h"
00047 #include "../containers/plonk_SimpleArray.h"
00048 
00049 
00050 template<class SenderContainerBaseType>
00051 class SenderInternal : public SmartPointer
00052 {
00053 public:    
00054     typedef typename SenderContainerBaseType::Internal          SenderInternalBaseType;    
00055     typedef ReceiverInternal<SenderContainerBaseType>           Receiver;
00056         
00057     typedef ObjectArrayInternal<Receiver*,SmartPointer>         RawReceiverArrayInternal;
00058     typedef ObjectArrayInternal<WeakPointer*,SmartPointer>      WeakReceiverOwnerArrayInternal;
00059 
00060     SenderInternal() throw();
00061     ~SenderInternal();
00062         
00063     void addReceiver(Receiver* const receiver) throw();
00064     void removeReceiver(Receiver* const receiver) throw();
00065     
00066     void addReceiver(WeakPointer* const owner, Receiver* const receiver) throw();
00067     void removeReceiver(WeakPointer* const owner, Receiver* const receiver) throw();
00068     
00069     void update (Text const& message, Dynamic const& payload) throw();
00070     void updateRaw (Text const& message, Dynamic const& payload) throw();
00071     void updateWeak (Text const& message, Dynamic const& payload) throw();
00072     
00073 private:
00074     SimpleArray<Receiver*>      rawReceivers;
00075     SimpleArray<WeakPointer*>   weakReceiverOwners;
00076     SimpleArray<Receiver*>      weakReceivers;
00077 };
00078 
00079 
00080 //------------------------------------------------------------------------------
00081 
00082 
00083 template<class SenderContainerBaseType>
00084 SenderInternal<SenderContainerBaseType>::SenderInternal() throw()
00085 {
00086 }
00087 
00088 
00089 template<class SenderContainerBaseType>
00090 SenderInternal<SenderContainerBaseType>::~SenderInternal()
00091 {
00092 }    
00093 
00094 template<class SenderContainerBaseType>
00095 void SenderInternal<SenderContainerBaseType>::addReceiver (Receiver* const receiver) throw()
00096 {
00097     plonk_assert (receiver != 0);
00098     
00099     if (rawReceivers.getInternal()->indexOf (receiver) < 0)
00100         rawReceivers.getInternal()->add (receiver);
00101 }
00102 
00103 template<class SenderContainerBaseType>
00104 void SenderInternal<SenderContainerBaseType>::removeReceiver (Receiver* const receiver) throw()
00105 {
00106     plonk_assert (receiver != 0);
00107     
00108     int index = rawReceivers.getInternal()->indexOf (receiver);
00109     
00110     if (index >= 0)
00111         rawReceivers.getInternal()->remove (index);  
00112 }
00113 
00114 template<class SenderContainerBaseType>
00115 void SenderInternal<SenderContainerBaseType>::addReceiver (WeakPointer* const owner, Receiver* const receiver) throw()
00116 {    
00117     plonk_assert (receiver != 0);
00118     plonk_assert (owner != 0);
00119     plonk_assert (owner->getWeakPointer() != 0);
00120             
00121     if (weakReceivers.getInternal()->indexOf (receiver) < 0)
00122     {
00123         plonk_assert (weakReceiverOwners.getInternal()->indexOf (owner) < 0);
00124         
00125         owner->incrementRefCount();
00126         weakReceiverOwners.getInternal()->add (owner);
00127         weakReceivers.getInternal()->add (receiver);
00128     }
00129 }
00130 
00131 template<class SenderContainerBaseType>
00132 void SenderInternal<SenderContainerBaseType>::removeReceiver (WeakPointer* const owner, Receiver* const receiver) throw()
00133 {
00134     plonk_assert (receiver != 0);
00135     plonk_assert (owner != 0);
00136 
00137     int index = weakReceivers.getInternal()->indexOf (receiver);
00138     
00139     if (index >= 0)
00140     {
00141         plonk_assert (weakReceiverOwners.getInternal()->indexOf (owner) == index);
00142         
00143         weakReceivers.getInternal()->remove (index);
00144         weakReceiverOwners.getInternal()->remove (index);
00145         owner->decrementRefCount();
00146     }
00147 }
00148 
00149 template<class SenderContainerBaseType>
00150 void SenderInternal<SenderContainerBaseType>::update (Text const& message, Dynamic const& payload) throw()
00151 {    
00152     this->updateRaw (message, payload);
00153     this->updateWeak (message, payload);
00154 }    
00155 
00156 template<class SenderContainerBaseType>
00157 void SenderInternal<SenderContainerBaseType>::updateRaw (Text const& message, Dynamic const& payload) throw()
00158 {    
00159     RawReceiverArrayInternal* arrayInternal = rawReceivers.getInternal();
00160     plonk_assert (arrayInternal != 0);
00161     
00162     const int numReceivers = arrayInternal->length();
00163     if (numReceivers > 0)
00164     {        
00165         SenderInternalBaseType* pthis = static_cast<SenderInternalBaseType*> (this);
00166         SenderContainerBaseType sender (pthis);            
00167         
00168         for (int i = numReceivers; --i >= 0;)
00169         {
00170             arrayInternal->getArray()[i]->changed (sender, message, payload);
00171         }
00172     }    
00173 }    
00174 
00175 template<class SenderContainerBaseType>
00176 void SenderInternal<SenderContainerBaseType>::updateWeak (Text const& message, Dynamic const& payload) throw()
00177 {    
00178     WeakReceiverOwnerArrayInternal* ownerArray = weakReceiverOwners.getInternal();
00179     plonk_assert (ownerArray != 0);
00180 
00181     const int numReceivers = ownerArray->length();
00182         
00183     if (numReceivers > 0)
00184     {     
00185         plonk_assert (weakReceivers.getInternal() != 0);
00186         plonk_assert (weakReceivers.getInternal()->length() == numReceivers);
00187         
00188         RawReceiverArrayInternal* reveiverArray = weakReceivers.getInternal();
00189         
00190         SenderInternalBaseType* pthis = static_cast<SenderInternalBaseType*> (this);
00191         SenderContainerBaseType sender (pthis);            
00192         
00193         for (int i = numReceivers; --i >= 0;)
00194         {            
00195             WeakPointer* owner = ownerArray->getArray()[i];
00196             Receiver* receiver = reveiverArray->getArray()[i];
00197             
00198             if (owner->getWeakPointer() != 0)
00199                 receiver->changed (sender, message, payload);
00200             else
00201                 this->removeReceiver (owner, receiver);
00202         }
00203     }    
00204 }    
00205 
00206 
00207 
00208 
00209 
00210 #endif // PLONK_SENDER_H
 All Classes Functions Typedefs Enumerations Enumerator Properties