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