00001 // 00002 // Copyright (c) 2005-2008 Kenichi Watanabe. 00003 // Copyright (c) 2005-2008 Yasuhiro Watari. 00004 // Copyright (c) 2005-2008 Hironori Ichibayashi. 00005 // Copyright (c) 2008-2009 Kazuo Horio. 00006 // Copyright (c) 2009-2013 Naruki Kurata. 00007 // Copyright (c) 2005-2013 Ryota Shioya. 00008 // Copyright (c) 2005-2013 Masahiro Goshima. 00009 // 00010 // This software is provided 'as-is', without any express or implied 00011 // warranty. In no event will the authors be held liable for any damages 00012 // arising from the use of this software. 00013 // 00014 // Permission is granted to anyone to use this software for any purpose, 00015 // including commercial applications, and to alter it and redistribute it 00016 // freely, subject to the following restrictions: 00017 // 00018 // 1. The origin of this software must not be misrepresented; you must not 00019 // claim that you wrote the original software. If you use this software 00020 // in a product, an acknowledgment in the product documentation would be 00021 // appreciated but is not required. 00022 // 00023 // 2. Altered source versions must be plainly marked as such, and must not be 00024 // misrepresented as being the original software. 00025 // 00026 // 3. This notice may not be removed or altered from any source 00027 // distribution. 00028 // 00029 // 00030 00031 00032 00033 #ifndef SIM_FOUNDATION_EVENT_PRIORITY_EVENT_LIST_H 00034 #define SIM_FOUNDATION_EVENT_PRIORITY_EVENT_LIST_H 00035 00036 #include "Sim/Foundation/Event/EventBase.h" 00037 #include "Sim/Foundation/TimeWheel/TimeWheelBase.h" 00038 #include "Sim/ResourcePriority.h" 00039 #include "Utility/Collection/fixed_size_buffer.h" 00040 00041 namespace Onikiri 00042 { 00043 class PriorityEventList 00044 { 00045 public: 00046 PriorityEventList() : 00047 m_updatePriority( RP_LOWEST ), 00048 m_evaluatePriority( RP_LOWEST ) 00049 { 00050 //m_eventList.resize( CRP_HIGHEST + 1 ); 00051 for( int i = RP_LOWEST; i < RP_HIGHEST + 1; i++ ){ 00052 m_eventList.push_back( new EventList ); 00053 } 00054 } 00055 00056 ~PriorityEventList() 00057 { 00058 for( PriorityList::iterator i = m_eventList.begin(); i != m_eventList.end(); ++i ){ 00059 delete *i; 00060 } 00061 m_eventList.clear(); 00062 } 00063 00064 //typedef EventPtr PtrType; 00065 typedef EventBaseImplement* PtrType; 00066 struct Entry 00067 { 00068 PtrType event; 00069 TimeWheelBase* timeWheel; 00070 00071 Entry( const PtrType& e, TimeWheelBase* t ) : 00072 event( e ), 00073 timeWheel( t ) 00074 { 00075 00076 } 00077 Entry() : 00078 event( 0 ), 00079 timeWheel( 0 ) 00080 { 00081 00082 } 00083 }; 00084 00085 //typedef pool_vector< Entry > EventList; 00086 enum MaxEvent{ MAX_EVENT_IN_ONE_CYCLE = 4096 }; 00087 typedef fixed_sized_buffer< Entry, MAX_EVENT_IN_ONE_CYCLE, MaxEvent > EventList; 00088 00089 enum MaxPriority{ MAX_PRIORITY = RP_HIGHEST + 1 }; 00090 typedef fixed_sized_buffer< EventList*, MAX_PRIORITY, MaxPriority > PriorityList; 00091 00092 typedef std::vector< TimeWheelBase* > TimeWheelList; 00093 00094 // Extract events processed in this cycle. 00095 // Events are extracted from 'timeWheels' to 'm_eventList'. 00096 void ExtractEvent( TimeWheelList* timeWheels ) 00097 { 00098 for( PriorityList::iterator i = m_eventList.begin(); i != m_eventList.end(); ++i ){ 00099 (*i)->clear(); 00100 } 00101 00102 // Extract events triggered in this cycle. 00103 TimeWheelList::iterator timeEnd = timeWheels->end(); 00104 for( TimeWheelList::iterator i = timeWheels->begin(); i != timeEnd; ++i ){ 00105 TimeWheelBase* wheel = *i; 00106 const TimeWheelBase::ListType& events = wheel->CurrentEvents(); 00107 TimeWheelBase::ListType::ConstIteratorType end = events.end(); 00108 for( TimeWheelBase::ListType::ConstIteratorType e = events.begin(); e != end; ++e ){ 00109 PtrType event = &(*e->event); 00110 if( !event->IsCanceled() ){ 00111 EventList* list = m_eventList[ event->GetPriority() ]; 00112 list->push_back( Entry( event, wheel ) ); 00113 } 00114 } 00115 } 00116 00117 } 00118 00119 void BeginEvaluate() 00120 { 00121 m_evaluatePriority = RP_HIGHEST; 00122 } 00123 00124 void TriggerEvaluate( int priority ) 00125 { 00126 int curPriority; 00127 for( curPriority = m_evaluatePriority; curPriority >= priority; curPriority-- ){ 00128 EventList* eventList = m_eventList[curPriority]; 00129 EventList::iterator eventEnd = eventList->end(); 00130 for( EventList::iterator i = eventList->begin(); i != eventEnd; ++i ){ 00131 i->event->TriggerEvaluate(); 00132 } 00133 } 00134 m_evaluatePriority = curPriority; 00135 } 00136 00137 void EndEvaluate() 00138 { 00139 TriggerEvaluate( RP_LOWEST ); 00140 } 00141 00142 00143 void BeginUpdate() 00144 { 00145 m_updatePriority = RP_HIGHEST; 00146 } 00147 00148 void TriggerUpdate( int priority ) 00149 { 00150 int curPriority; 00151 for( curPriority = m_updatePriority; curPriority >= priority; curPriority-- ){ 00152 EventList* eventList = m_eventList[curPriority]; 00153 EventList::iterator eventEnd = eventList->end(); 00154 for( EventList::iterator i = eventList->begin(); i != eventEnd; ++i ){ 00155 if( !i->timeWheel->IsStalledThisCycle() ){ 00156 i->event->TriggerUpdate(); 00157 } 00158 } 00159 } 00160 m_updatePriority = curPriority; 00161 } 00162 00163 void EndUpdate() 00164 { 00165 TriggerUpdate( RP_LOWEST ); 00166 } 00167 00168 private: 00169 00170 PriorityList m_eventList; 00171 int m_updatePriority; 00172 int m_evaluatePriority; 00173 }; 00174 00175 } //namespace Onikiri 00176 00177 00178 00179 #endif 00180