1 /*************************************************************************
2  *                                                                       *
3  * Tokamak Physics Engine, Copyright (C) 2002-2007 David Lam.            *
4  * All rights reserved.  Email: david@tokamakphysics.com                 *
5  *                       Web: www.tokamakphysics.com                     *
6  *                                                                       *
7  * This library is distributed in the hope that it will be useful,       *
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
10  * LICENSE.TXT for more details.                                         *
11  *                                                                       *
12  *************************************************************************/
13 
14 #ifndef NE_STACK_H
15 #define NE_STACK_H
16 
17 #define NE_MAX_REST_ON 3
18 
19 class neStackHeader;
20 
21 class neStackInfo
22 {
23 public:
Init()24 	void Init()
25 	{
26 		stackHeader = NULL;
27 		body = NULL;
28 		isTerminator = true;
29 		isBroken = false;
30 	}
31 	void Resolve();
32 
33 	void AddToSolver(neBool addCheader);
34 
35 	neStackHeader * CheckAcceptNewHeader(neStackHeader * newHeader);
36 
37 	void ForceAcceptNewHeader(neStackHeader * newHeader);
38 
39 	//void Break();
40 
41 	void CheckHeader(neStackHeader * sh);
42 
43 	neBool isResolved;
44 	neBool isTerminator;
45 	neBool isBroken;
46 	neStackHeader * stackHeader;
47 	neRigidBody_ * body;
48 	s32 startTime;
49 	s32 endTime;
50 
51 	//neRestRecord restRecords[neRigidBody_::NE_RB_MAX_RESTON_RECORDS];
52 };
53 
54 typedef neDLinkList<neStackInfo> neStackInfoHeap;
55 
56 typedef neFreeListItem<neStackInfo> neStackInfoItem;
57 
58 class neStackHeader
59 {
60 public:
61 	neFixedTimeStepSimulator * sim;
62 
63 	neStackInfo * head;
64 	neStackInfo * tail;
65 	s32 infoCount;
66 	neBool isHeaderX;
67 	neBool isAllIdle;
68 	static s32 golbalTime;
69 	neBool dynamicSolved;
70 
Null()71 	void Null()
72 	{
73 		head = NULL;
74 
75 		tail = NULL;
76 
77 		infoCount = 0;
78 
79 		isHeaderX = false;
80 
81 		isAllIdle = false;
82 
83 		dynamicSolved = false;
84 	}
85 
86 	//void Purge();
87 
88 	void Resolve();
89 
CheckLength()90 	void CheckLength()
91 	{
92 		s32 c = 0;
93 
94 		neStackInfoItem * item = (neStackInfoItem *) head;
95 
96 		while (item)
97 		{
98 			ASSERT(c < infoCount);
99 
100 			c++;
101 
102 			item = item->next;
103 		}
104 	}
CheckHeader()105 	void CheckHeader()
106 	{
107 		ASSERT(infoCount != 0);
108 
109 		s32 c = 0;
110 
111 		neStackInfoItem * item = (neStackInfoItem *) head;
112 
113 		while (item)
114 		{
115 			ASSERT(c < infoCount);
116 
117 			c++;
118 
119 			neStackInfo * sinfo = (neStackInfo*) item;
120 
121 			ASSERT(sinfo->stackHeader == this);
122 
123 			if (!sinfo->isTerminator)
124 				sinfo->CheckHeader(this);
125 
126 			item = item->next;
127 		}
128 		ASSERT(c == infoCount);
129 	}
Add(neStackInfo * add)130 	void Add(neStackInfo * add)
131 	{
132 		if (!head)
133 		{
134 			head = tail = add;
135 
136 			ASSERT(((neStackInfoItem*)add)->next == NULL);
137 		}
138 		else
139 		{
140 			ASSERT(add != tail);
141 
142 			((neStackInfoItem*)tail)->Append((neStackInfoItem*)add);
143 
144 			tail = add;
145 		}
146 		infoCount++;
147 
148 		add->stackHeader = this;
149 	}
150 	void Remove(neStackInfo * add, s32 flag = 0)
151 	{
152 /*		if (infoCount == 1 && !isHeaderX && flag == 0)
153 			ASSERT(0);
154 */
155 		neStackInfoItem * item = (neStackInfoItem *)add;
156 
157 		if (head == add)
158 			head = (neStackInfo*)item->next;
159 
160 		if (tail == add)
161 			tail = (neStackInfo*)item->prev;
162 
163 		item->Remove();
164 
165 		infoCount--;
166 
167 		add->stackHeader = NULL;
168 	}
Check(neStackInfo * st)169 	neBool Check(neStackInfo * st)
170 	{
171 		s32 c = 0;
172 
173 		neStackInfoItem * item = (neStackInfoItem *) head;
174 
175 		while (item)
176 		{
177 			ASSERT(c < infoCount);
178 
179 			c++;
180 
181 			neStackInfo * sinfo = (neStackInfo*) item;
182 
183 			ASSERT(sinfo->stackHeader == this);
184 
185 			if (st == sinfo)
186 			{
187 				return true;
188 			}
189 			item = item->next;
190 		}
191 		return false;
192 	}
193 	neBool CheckStackDisconnected();
194 
GetBottomStackBody()195 	neRigidBody_ * GetBottomStackBody()
196 	{
197 		return NULL;
198 /*		if (!head)
199 			return NULL;
200 
201 		neStackInfoItem * item = (neStackInfoItem *) head;
202 
203 		while (item)
204 		{
205 			neStackInfo * sinfo = (neStackInfo *) item;
206 
207 			neRigidBody_ * body = sinfo->body;
208 
209 			neStackInfo * nextSinfo = NULL;
210 
211 			for (s32 i = 0; i < sinfo->restOnCount; i++)
212 			{
213 				ASSERT (sinfo->restOn[i].body);
214 
215 				if (sinfo->restOn[i].body->stackInfo)
216 				{
217 					if (sinfo->restOn[i].body->stackHeader == NULL)
218 					{
219 
220 					}
221 					else
222 					{
223 						nextSinfo = sinfo->restOn[i].body->stackInfo;
224 						break;
225 					}
226 				}
227 				else
228 				{
229 					//return sinfo->restOn[i].body;
230 				}
231 			}
232 			if (nextSinfo != NULL)
233 			{
234 				item = (neStackInfoItem *)nextSinfo;
235 			}
236 			else
237 			{
238 				return sinfo->body;
239 			}
240 		}
241 		ASSERT(0);
242 		return NULL;
243 */	}
244 	void ChangeHeader(neStackHeader * newHeader);
245 
246 	void AddToSolver(/*neBool withConstraint*/);
247 
248 	void AddToSolverNoConstraintHeader();
249 
250 	void ResetRigidBodyFlag();
251 };
252 
253 typedef neDLinkList<neStackHeader> neStackHeaderHeap;
254 
255 typedef neFreeListItem<neStackHeader> neStackHeaderItem;
256 
257 #endif //NE_STACK_H
258