00001 /* 00002 * This file contains simple working unit from that may be simply derived others units. 00003 * 00004 * Author: 00005 * Tomas Mrkvicka 00006 * xmrkvi03@stud.fit.vutbr.cz 00007 * 00008 */ 00009 00010 #include <windows.h> 00011 00012 // FORWARD DECLARATIONS 00013 namespace NSPipeline 00014 { 00015 class TSimpleUnit; 00016 class TSimpleUnitProcessingInterface; 00017 }; 00018 00019 #ifndef _PIPELINE_SIMPLEUNIT_HH_ 00020 #define _PIPELINE_SIMPLEUNIT_HH_ 00021 00022 #include "pipeline/Unit.h" 00023 #include "pipeline/Thread.h" 00024 #include "pipeline/CriticalSection.h" 00025 00026 namespace NSPipeline 00027 { 00028 00029 //////////////////////////////////////////////////////////////////////////////// 00030 //////////////////////////////////////////////////////////////////////////////// 00031 //////////////////////////////////////////////////////////////////////////////// 00032 // TSimpleUnitProcessingInterface 00033 00034 /** Toto je rozhrani pro objekty, ktere zajistuji vypocet v ramci jednotky TSimpleUnit. 00035 * 00036 * STACI ODVODIT NOVOU TRIDU OD TOHOTO ROZHRANI A PREPSAT METODY PROCESSFRAME() A DESTRUKTOR. 00037 * 00038 * METODY GETTYPE() A GETRESULT() BYT POVINNE PREPSANY NEMUSI, ALE VETSINOU JE TO NUTNE. IMPLICITNE 00039 * TOTIZ TYTO METODY REPREZENTUJI JEDNOTKU, KTERA NEVRACI ZADNA DATA. 00040 * 00041 * Metoda ProcessFrame je pracovni metodou, ktera je automaticky volana tridou TSimpleUnit. 00042 * V teto metode musi byt zpracovan zadany snimek TFrame. Metoda se nemusi starat o reference 00043 * ani zamky, pouze zpracuje snimek. Metoda musi probehnout naprosto bez chyb, pokud dojde 00044 * k nejakemu selhani pak musi byt zpracovano uvnitr metody a navenek se nesmi projevit - tedy 00045 * nejsou povoleny zadne vyjimky apod. 00046 * 00047 * Dale je nutne prepsat metody GetType() a GetResult(). 00048 * Pokud tyto dve nejsou prepsany, pak trida nevraci zadna data a metoda 00049 * GetResult vraci vzdy NULL. 00050 * 00051 * Tato trida (a z ni odvozene) je vzdy odpovedna za objekt, ktery je vracen metodou 00052 * GetResult(). 00053 */ 00054 class TSimpleUnitProcessingInterface 00055 { 00056 //PUBLIC ABSTRACT METHODS 00057 public: 00058 /** Tato metoda obdrzi snimek, zpracuje jej a ukonci se. 00059 * O jeji volani se stara logika uvnitr tridy TSimpleUnit. 00060 */ 00061 virtual void ProcessFrame( const TFrame * frame ) = 0; 00062 00063 /** Virtualni destruktor. 00064 */ 00065 virtual ~TSimpleUnitProcessingInterface(void) = 0 {}; 00066 00067 /** Datovy typ ukladany v teto tride. 00068 * 00069 * Imlicitni implementace predpokladany, ze jendotka nevraci zadna data. 00070 */ 00071 virtual EnumUnitType GetType(void) const { return ENUM_UNITTYPE_NODATA; }; 00072 00073 /** Ukazatel na vracena data pro snimek se zadanym ID. 00074 * 00075 * Metoda muze vratit NULL. V bazove tride vraci NULL vzdy. 00076 * 00077 * Tato metoda by mela byt synchronizovana pro soubezny pristup vice vlakne, nebot 00078 * jedno vlakno (z vypocetni jednotky) do objektu zapisuje data a v takovem pripade 00079 * musi metoda GetResult() pockat na jejich zapis. 00080 * 00081 * Implpicitni navratova hodnota je NULL. 00082 */ 00083 virtual TUnitRetTypeInterface* GetResult( DWORD id ) { return NULL; }; 00084 }; 00085 //OK 2007-08-25 18:31:09 B04-315B\Tom 00086 00087 // TSimpleUnitProcessingInterface 00088 //////////////////////////////////////////////////////////////////////////////// 00089 //////////////////////////////////////////////////////////////////////////////// 00090 //////////////////////////////////////////////////////////////////////////////// 00091 // TSimpleUnit 00092 00093 /** Tato trida reprezentuje jednotku, ktera zpracovava 00094 * data vzdy pouze z jednoho snimku. 00095 * 00096 * POUZITI: 00097 * 00098 * (A) JEDNOTKA KTERA NEVRACI ZADNA DATA 00099 * 00100 * (1) Vytvorit tridu pro vypocet nad snimkem odvozenou od TSimpleUnitProcessingInterface 00101 * s prepsanou metodou ProcessFrame(). Takova trida nevraci zadna data. 00102 * (2) Pouzit objekt teto tridy primo v kontruktoru tridy TSimpleUnit. 00103 * 00104 * (B) JEDNOTKA VRACEJICI DATA 00105 * 00106 * (1) Vytvorit tridu pro vypocet nad snimkem odvozenou od TSimpleUnitProcessingInterface. 00107 * Reimplementovat VSECHNY jeji metody. To zahrnuje vybrani (pripadne nadefinovani noveho) 00108 * navratoveho datoveho typu. 00109 * (2) Pouzit objekt teto tridy primo v kontruktoru tridy TSimpleUnit. 00110 */ 00111 class TSimpleUnit: public TUnitInterface 00112 { 00113 enum EnumUnitState; 00114 00115 //PUBLIC OVERRIDEN METHODS 00116 public: 00117 /** Typ teto jednotky a zaroven typ navratove hodnoty 00118 */ 00119 virtual EnumUnitType GetType(void) { return m_unit->GetType(); }; 00120 00121 /** Vysledek vraceny jednotkou. 00122 */ 00123 virtual TUnitRetTypeInterface* GetResult(DWORD id) { return m_unit->GetResult( id ); } 00124 00125 /** Pocet snimku, ktere nebyly zpracovany mezi poslednimi dvema zpracovanymi snimky. 00126 */ 00127 virtual DWORD GetFrameInterval() { return m_interval; }; 00128 00129 virtual BOOL Start(void); 00130 virtual BOOL Stop(void); 00131 00132 virtual void Release(void); 00133 00134 //PUBLIC METHODS 00135 public: 00136 TSimpleUnit( TDispatcherInterface* dispatcher, TSimpleUnitProcessingInterface * unit, BOOL lockFrame); 00137 00138 //PROTECTED METHODS 00139 protected: 00140 ~TSimpleUnit(void); 00141 00142 //PRIVATE METHODS 00143 private: 00144 static DWORD WINAPI TSimpleUnitThread(void* ptr); 00145 00146 00147 EnumUnitState GetState(void) const; 00148 void SetState(EnumUnitState state); 00149 00150 void Loop(void); 00151 00152 //PROTECTED FAKE METHODS 00153 protected: 00154 TSimpleUnit( const TSimpleUnit & orig ); ///< falesny kopirovaci konstruktor 00155 void operator=( const TSimpleUnit & orig ); ///< falesny prirazovaci operator 00156 00157 //PRIVATE STRUCTURES 00158 private: 00159 /** Enumerator s moznymi stavy stavoveho automatu uvnitr jednotky. 00160 */ 00161 enum EnumUnitState 00162 { 00163 ENUM_UNIT_WORK, ///< jednotka zpracovava snimek, po dokonceni prejde 00164 ///< do stavu ENUM_UNIT_LOADFRAME 00165 ///< z tohoto stavu muze jednotka prejit take do stavu 00166 ///< ENUM_PROC_FINISHWORK aby bylo mozne ukoncit/prerusit jeji cinnost 00167 ENUM_UNIT_LOADFRAME, ///< jednotka je pripravena ziskat dalsi snimek, po ziskani snimku 00168 ///< prejde do ENUM_UNIT_WORK 00169 ///< z tohoto stavu muze jednotka prejit take do stavu 00170 ///< ENUM_UNIT_FINISHWORK aby bylo mozne ukoncit/prerusit jeji cinnost 00171 ///< toto je zaroven pocatecni stav jednotky po spusteni 00172 ENUM_UNIT_FINISHWORK, ///< jednotka zpracovava snimek, po dokonceni zastavi svou cinnost 00173 ///< prechodem do ENUM_UNIT_STOP 00174 ENUM_UNIT_STOP ///< signalizace zastaveni jednotky 00175 }; 00176 00177 //PRIVATE COMPONENTS 00178 private: 00179 BOOL m_lockFrame; ///< urcuje zda tato jednotka zamyka snimky 00180 00181 volatile DWORD m_interval; ///< pocet snimku, ktere jednotka nestihla 00182 ///< zpracovat pred zpracovanim posledniho snimku 00183 00184 EnumUnitState m_state; ///< aktualni stav jednotky 00185 TCriticalSection m_critical; ///< kriticka sekce pro zmenu stavu jednotky 00186 00187 TThread* m_thread; ///< vlakno bezici v jednotce 00188 ///< pokud je NULL pak jednotka nebezi 00189 00190 TDispatcherInterface* m_dispatcher; ///< rozhrani k dispatcheru snimku 00191 00192 TFrame* m_frame; ///< prave ulozeny snimek 00193 ///< je nad nim drzena reference 00194 ///< a take zamek pokud jednotka zamyka snimky 00195 00196 TSimpleUnitProcessingInterface* m_unit; ///< objekt pro vlastni vypocty 00197 }; 00198 //OK 2007-08-25 18:42:08 B04-315B\Tom 00199 00200 /** Vrati aktualni stav stavoveho automatu ktery ridi vypocet. 00201 */ 00202 inline TSimpleUnit::EnumUnitState TSimpleUnit::GetState(void) const 00203 { 00204 return m_state; 00205 } 00206 //OK 2007-08-25 18:42:17 B04-315B\Tom 00207 00208 /** Nastavi novy stav stavoveho automatu, ktery ridi vypocet. 00209 * 00210 * \param state [in] novy stav 00211 */ 00212 inline void TSimpleUnit::SetState( TSimpleUnit::EnumUnitState state) 00213 { 00214 m_state = state; 00215 } 00216 //OK 2007-08-25 18:42:19 B04-315B\Tom 00217 00218 // TSimpleUnit 00219 //////////////////////////////////////////////////////////////////////////////// 00220 //////////////////////////////////////////////////////////////////////////////// 00221 //////////////////////////////////////////////////////////////////////////////// 00222 00223 }; //end of NSPipeline 00224 using namespace NSPipeline; 00225 00226 #endif