00001 //<<<<<< INCLUDES >>>>>> 00002 00003 #include "Iguana/Framework/interface/IgState.h" 00004 #include "Iguana/Framework/interface/IgStateKey.h" 00005 #include "Iguana/Framework/interface/IgStateElement.h" 00006 #include "classlib/utils/DebugAids.h" 00007 #include <algorithm> 00008 00009 //<<<<<< PRIVATE DEFINES >>>>>> 00010 //<<<<<< PRIVATE CONSTANTS >>>>>> 00011 //<<<<<< PRIVATE TYPES >>>>>> 00012 //<<<<<< PRIVATE VARIABLE DEFINITIONS >>>>>> 00013 //<<<<<< PUBLIC VARIABLE DEFINITIONS >>>>>> 00014 //<<<<<< CLASS STRUCTURE INITIALIZATION >>>>>> 00015 //<<<<<< PRIVATE FUNCTION DEFINITIONS >>>>>> 00016 //<<<<<< PUBLIC FUNCTION DEFINITIONS >>>>>> 00017 //<<<<<< MEMBER FUNCTION DEFINITIONS >>>>>> 00018 00020 void 00021 IgState::addChild (IgState *child) 00022 { 00023 ASSERT (child); 00024 ASSERT (std::find (m_children.begin (), m_children.end (), child) 00025 == m_children.end ()); 00026 00027 m_children.push_back (child); 00028 } 00029 00031 void 00032 IgState::detachChild (IgState *child) 00033 { 00034 ASSERT (child); 00035 Children::iterator pos 00036 = std::find (m_children.begin (), m_children.end (), child); 00037 00038 ASSERT (pos != m_children.end ()); 00039 00040 m_children.erase (pos); 00041 } 00042 00044 00045 IgState::IgState (IgState *parent /* = 0 */) 00046 : m_parent (parent) 00047 { if (m_parent) m_parent->addChild (this); } 00048 00050 IgState::~IgState (void) 00051 { 00052 if (m_parent) 00053 m_parent->detachChild (this); 00054 00055 while (! m_children.empty ()) 00056 delete m_children.front (); 00057 00058 for (Elements::size_type i = 0; i < m_elements.size (); ++i) 00059 delete m_elements [i]; 00060 } 00061 00063 00065 IgState * 00066 IgState::root (void) const 00067 { 00068 IgState *s = const_cast<IgState *> (this); 00069 while (s->m_parent) 00070 s = s->m_parent; 00071 00072 return s; 00073 } 00074 00076 IgState * 00077 IgState::parent (void) const 00078 { return m_parent; } 00079 00081 unsigned 00082 IgState::children (void) const 00083 { return m_children.size (); } 00084 00089 IgState * 00090 IgState::child (unsigned index) const 00091 { ASSERT (index < m_children.size ()); return m_children [index]; } 00092 00094 00099 IgStateElement * 00100 IgState::get (IgStateKey index, IgState **context /* = 0 */) const 00101 { 00102 IgState *in = const_cast<IgState *> (this); 00103 IgStateElement *element = 0; 00104 00105 for ( ; in && ! element; in = in->parent ()) 00106 if (index < in->m_elements.size ()) 00107 element = in->m_elements [index]; 00108 00109 if (context) 00110 *context = in; 00111 00112 return element; 00113 } 00114 00122 void 00123 IgState::put (IgStateKey index, IgStateElement *element) 00124 { 00125 if (index >= m_elements.size ()) 00126 { 00127 if (! element) 00128 return; 00129 else 00130 m_elements.resize (index+1, 0); 00131 } 00132 00133 if (m_elements [index] != element) 00134 { 00135 // Destructor must call detach() 00136 delete m_elements [index]; 00137 ASSERT (m_elements [index] == 0); 00138 } 00139 00140 m_elements [index] = element; 00141 } 00142 00145 void 00146 IgState::erase (IgStateKey index) 00147 { put (index, 0); } 00148 00153 void 00154 IgState::detach (IgStateKey index) 00155 { 00156 ASSERT (index <= m_elements.size ()); 00157 ASSERT (m_elements [index]); 00158 m_elements [index] = 0; 00159 } 00160 00164 unsigned 00165 IgState::elements (void) const 00166 { return m_elements.size (); } 00167 00173 IgStateElement * 00174 IgState::element (unsigned index) const 00175 { ASSERT (index < m_elements.size ()); return m_elements [index]; }