1 /* 2 ** dthinker.h 3 ** 4 **--------------------------------------------------------------------------- 5 ** Copyright 1998-2006 Randy Heit 6 ** All rights reserved. 7 ** 8 ** Redistribution and use in source and binary forms, with or without 9 ** modification, are permitted provided that the following conditions 10 ** are met: 11 ** 12 ** 1. Redistributions of source code must retain the above copyright 13 ** notice, this list of conditions and the following disclaimer. 14 ** 2. Redistributions in binary form must reproduce the above copyright 15 ** notice, this list of conditions and the following disclaimer in the 16 ** documentation and/or other materials provided with the distribution. 17 ** 3. The name of the author may not be used to endorse or promote products 18 ** derived from this software without specific prior written permission. 19 ** 20 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 **--------------------------------------------------------------------------- 31 ** 32 */ 33 34 #ifndef __DTHINKER_H__ 35 #define __DTHINKER_H__ 36 37 #include <stdlib.h> 38 #include "dobject.h" 39 #include "statnums.h" 40 41 class AActor; 42 class player_t; 43 struct pspdef_s; 44 struct FState; 45 46 class FThinkerIterator; 47 48 enum { MAX_STATNUM = 127 }; 49 50 // Doubly linked ring list of thinkers 51 struct FThinkerList 52 { FThinkerListFThinkerList53 FThinkerList() : Sentinel(0) {} 54 void AddTail(DThinker *thinker); 55 DThinker *GetHead() const; 56 DThinker *GetTail() const; 57 bool IsEmpty() const; 58 59 DThinker *Sentinel; 60 }; 61 62 class DThinker : public DObject 63 { 64 DECLARE_CLASS (DThinker, DObject) 65 public: 66 DThinker (int statnum = STAT_DEFAULT) throw(); 67 void Destroy (); 68 virtual ~DThinker (); 69 virtual void Tick (); 70 virtual void PostBeginPlay (); // Called just before the first tick 71 size_t PropagateMark(); 72 73 void ChangeStatNum (int statnum); 74 75 static void RunThinkers (); 76 static void RunThinkers (int statnum); 77 static void DestroyAllThinkers (); 78 static void DestroyMostThinkers (); 79 static void SerializeAll (FArchive &arc, bool keepPlayers); 80 static void MarkRoots(); 81 82 static DThinker *FirstThinker (int statnum); 83 84 private: 85 enum no_link_type { NO_LINK }; 86 DThinker(no_link_type) throw(); 87 static void DestroyThinkersInList (FThinkerList &list); 88 static void DestroyMostThinkersInList (FThinkerList &list, int stat); 89 static int TickThinkers (FThinkerList *list, FThinkerList *dest); // Returns: # of thinkers ticked 90 static void SaveList(FArchive &arc, DThinker *node); 91 void Remove(); 92 93 static FThinkerList Thinkers[MAX_STATNUM+2]; // Current thinkers 94 static FThinkerList FreshThinkers[MAX_STATNUM+1]; // Newly created thinkers 95 static bool bSerialOverride; 96 97 friend struct FThinkerList; 98 friend class FThinkerIterator; 99 friend class DObject; 100 101 DThinker *NextThinker, *PrevThinker; 102 }; 103 104 class FThinkerIterator 105 { 106 protected: 107 const PClass *m_ParentType; 108 private: 109 DThinker *m_CurrThinker; 110 BYTE m_Stat; 111 bool m_SearchStats; 112 bool m_SearchingFresh; 113 114 public: 115 FThinkerIterator (const PClass *type, int statnum=MAX_STATNUM+1); 116 FThinkerIterator (const PClass *type, int statnum, DThinker *prev); 117 DThinker *Next (); 118 void Reinit (); 119 }; 120 121 template <class T> class TThinkerIterator : public FThinkerIterator 122 { 123 public: FThinkerIterator(RUNTIME_CLASS (T),statnum)124 TThinkerIterator (int statnum=MAX_STATNUM+1) : FThinkerIterator (RUNTIME_CLASS(T), statnum) 125 { 126 } TThinkerIterator(int statnum,DThinker * prev)127 TThinkerIterator (int statnum, DThinker *prev) : FThinkerIterator (RUNTIME_CLASS(T), statnum, prev) 128 { 129 } FThinkerIterator(subclass,statnum)130 TThinkerIterator (const PClass *subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(subclass, statnum) 131 { 132 } FThinkerIterator(PClass::FindClass (subclass),statnum)133 TThinkerIterator (FName subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(PClass::FindClass(subclass), statnum) 134 { 135 } FThinkerIterator(PClass::FindClass (subclass),statnum)136 TThinkerIterator (ENamedName subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(PClass::FindClass(subclass), statnum) 137 { 138 } FThinkerIterator(PClass::FindClass (subclass),statnum)139 TThinkerIterator (const char *subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(PClass::FindClass(subclass), statnum) 140 { 141 } Next()142 T *Next () 143 { 144 return static_cast<T *>(FThinkerIterator::Next ()); 145 } 146 }; 147 148 #endif //__DTHINKER_H__ 149