1 /*! 2 * \file comp_attach_pt_t.h 3 * \brief OpenCSD : Component attachment point interface class. 4 * 5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. 6 */ 7 8 /* 9 * Redistribution and use in source and binary forms, with or without modification, 10 * are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the copyright holder nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #ifndef ARM_COMP_ATTACH_PT_T_H_INCLUDED 36 #define ARM_COMP_ATTACH_PT_T_H_INCLUDED 37 38 #include <vector> 39 #include "opencsd/ocsd_if_types.h" 40 41 /** @defgroup ocsd_infrastructure OpenCSD Library : Library Component Infrastructure 42 43 @brief Classes providing library infrastructure and auxilary functionality 44 @{*/ 45 46 #include "comp_attach_notifier_i.h" 47 48 /*! 49 * @class componentAttachPt 50 * @brief Single component interface pointer attachment point. 51 * 52 * This is a class template to standardise the connections between decode components. 53 * 54 * An attachment point connects a component interface pointer to the component providing the 55 * attachment point. 56 * 57 * This attachment point implementation allows a single interface to be connected. 58 * 59 */ 60 template <class T> 61 class componentAttachPt { 62 public: 63 componentAttachPt(); /**< Default constructor */ 64 virtual ~componentAttachPt(); /**< Default destructor */ 65 66 /*! 67 * Attach an interface of type T to the attachment point. 68 * 69 * @param component : interface to attach. 70 * 71 * @return ocsd_err_t : OCSD_OK if successful, OCSD_ERR_ATTACH_TOO_MANY if too many connections. 72 */ 73 virtual ocsd_err_t attach(T* component); 74 75 /*! 76 * Detach component from the attachment point. 77 * 78 * @param component : Component to detach. 79 * 80 * @return virtual ocsd_err_t : OCSD_OK if successful, OCSD_ERR_ATTACH_COMP_NOT_FOUND if no match to component. 81 */ 82 virtual ocsd_err_t detach(T* component); 83 84 85 // detach current first if anything attached, connect supplied pointer, remain unattached if pointer 0 86 virtual ocsd_err_t replace_first(T* component); 87 88 /*! 89 * Detach all components. 90 */ 91 virtual void detach_all(); 92 93 /*! 94 * Return the current (first) attached interface pointer. 95 * Will return 0 if nothing attached or the attachment point is disabled. 96 * 97 * @return T* : Current Interface pointer of type T or 0. 98 */ 99 virtual T* first(); 100 101 /*! 102 * Return the next attached interface. 103 * The componentAttachPt base implmentation will always return 0 as only a single attachment is possible 104 * 105 * @return T* : Always returns 0. 106 */ 107 virtual T* next(); 108 109 /*! 110 * Returns the number of interface pointers attached to this attachment point. 111 * 112 * @return int : number of component interfaces attached. 113 */ 114 virtual int num_attached(); 115 116 /*! 117 * Attach a notifier interface to the attachment point. Will call back on this interface whenever 118 * a component is attached or detached. 119 * 120 * @param *notifier : pointer to the IComponentAttachNotifier interface. 121 */ 122 void set_notifier(IComponentAttachNotifier *notifier); 123 124 /* enable state does not affect attach / detach, but can be used to filter access to interfaces */ 125 const bool enabled() const; /**< return the enabled flag. */ 126 void set_enabled(const bool enable); 127 128 129 /*! 130 * Check to see if any attachements. Will return attach state independent of enable state. 131 * 132 * @return const bool : true if attachment. 133 */ 134 const bool hasAttached() const { return m_hasAttached; }; 135 136 137 /*! 138 * Return both the attachment and enabled state. 139 * 140 * @return const bool : true if both has attachment and is enabled. 141 */ 142 const bool hasAttachedAndEnabled() const { return m_hasAttached && m_enabled; }; 143 144 protected: 145 bool m_enabled; /**< Flag to indicate if the attachment point is enabled. */ 146 bool m_hasAttached; /**< Flag indicating at least one attached interface */ 147 IComponentAttachNotifier *m_notifier; /**< Optional attachement notifier interface. */ 148 T *m_comp; /**< pointer to the single attached interface */ 149 }; 150 151 152 153 template<class T> componentAttachPt<T>::componentAttachPt() 154 { 155 m_comp = 0; 156 m_notifier = 0; 157 m_enabled = true; 158 m_hasAttached = false; 159 } 160 161 template<class T> componentAttachPt<T>::~componentAttachPt() 162 { 163 detach_all(); 164 } 165 166 167 template<class T> ocsd_err_t componentAttachPt<T>::attach(T* component) 168 { 169 if(m_comp != 0) 170 return OCSD_ERR_ATTACH_TOO_MANY; 171 m_comp = component; 172 if(m_notifier) m_notifier->attachNotify(1); 173 m_hasAttached = true; 174 return OCSD_OK; 175 } 176 177 template<class T> ocsd_err_t componentAttachPt<T>::replace_first(T* component) 178 { 179 if(m_hasAttached) 180 detach(m_comp); 181 182 if(component == 0) 183 return OCSD_OK; 184 185 return attach(component); 186 } 187 188 template<class T> ocsd_err_t componentAttachPt<T>::detach(T* component) 189 { 190 if(m_comp != component) 191 return OCSD_ERR_ATTACH_COMP_NOT_FOUND; 192 m_comp = 0; 193 m_hasAttached = false; 194 if(m_notifier) m_notifier->attachNotify(0); 195 return OCSD_OK; 196 } 197 198 template<class T> T* componentAttachPt<T>::first() 199 { 200 return (m_enabled) ? m_comp : 0; 201 } 202 203 template<class T> T* componentAttachPt<T>::next() 204 { 205 return 0; 206 } 207 208 template<class T> int componentAttachPt<T>::num_attached() 209 { 210 return ((m_comp != 0) ? 1 : 0); 211 } 212 213 template<class T> void componentAttachPt<T>::detach_all() 214 { 215 m_comp = 0; 216 m_hasAttached = false; 217 if(m_notifier) m_notifier->attachNotify(0); 218 } 219 220 template<class T> void componentAttachPt<T>::set_notifier(IComponentAttachNotifier *notifier) 221 { 222 m_notifier = notifier; 223 } 224 225 template<class T> const bool componentAttachPt<T>::enabled() const 226 { 227 return m_enabled; 228 } 229 230 template<class T> void componentAttachPt<T>::set_enabled(const bool enable) 231 { 232 m_enabled = enable; 233 } 234 235 236 /** @}*/ 237 238 #endif // ARM_COMP_ATTACH_PT_T_H_INCLUDED 239 240 /* End of File comp_attach_pt_t.h */ 241