![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
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