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