Commits

jeffw  committed 313a7c1

Shapes no longer use opaque lists.

  • Participants
  • Parent commits 66adf3a

Comments (0)

Files changed (4)

File src/Collision/Shapes/Shape.cs

 	/// You can use shape for collision detection before they are attached to the world.
 	/// Warning: you cannot reuse shapes.
 	/// </summary>
-	public abstract class Shape : IDisposable
+	public abstract class Shape
 	{
         // Assigned by shape definition
         protected ShapeType _type;
         // Defaults
         protected ushort _proxyId = PairManager.NullProxy;
         protected Body _body;
-        protected Shape _next;
         protected float _sweepRadius;
         protected bool _isSensor;
         protected object _userData;
 		public ShapeType Type { get { return _type; } }
 		
 		/// <summary>
-		/// Get the next shape in the parent body's shape list.
-		/// </summary>
-		public Shape Next 
-        { 
-            get { return _next; }
-            internal set { _next = value; }
-        }
-		
-		/// <summary>
 		/// Get the parent body of this shape. This is NULL if the shape is not attached.
 		/// </summary>
 		public Body Body 
 			}
 		}
 
-		internal static void Destroy(Shape s)
-		{
-			switch (s.Type)
-			{
-				case ShapeType.CircleShape:
-					if (s is IDisposable)
-						(s as IDisposable).Dispose();
-					s = null;
-					break;
-
-				case ShapeType.PolygonShape:
-					if (s is IDisposable)
-						(s as IDisposable).Dispose();
-					s = null;
-					break;
-
-				default:
-					Debug.Assert(false);
-					break;
-			}
-		}
-
 		internal void CreateProxy(BroadPhase broadPhase, XForm transform)
 		{
 			Debug.Assert(_proxyId == PairManager.NullProxy);
 				_proxyId = PairManager.NullProxy;
 			}
 		}
-
-		public virtual void Dispose()
-		{
-			Debug.Assert(_proxyId == PairManager.NullProxy);
-		}
 	}
 }

File src/Dynamics/Body.cs

 	/// <summary>
 	/// A rigid body.
 	/// </summary>
-	public class Body : IDisposable
+	public class Body
 	{
 
 		[Flags]
 
 		private World _world;
 
-		internal Shape _shapeList;
-		internal int _shapeCount;
-
-        internal LinkedList<Joint> _jointList = new LinkedList<Joint>();
+		internal LinkedList<Joint> _jointList = new LinkedList<Joint>();
         internal LinkedList<ContactEdge> _contactList = new LinkedList<ContactEdge>();
+        internal LinkedList<Shape> _shapeList = new LinkedList<Shape>();
 
 		internal float _mass;
 		internal float _invMass;
 			}
 
 			_userData = bd.UserData;
-
-			_shapeList = null;
-			_shapeCount = 0;
 		}
 
         public void AddContact(ContactEdge aEdge)
             _contactList.Remove(aEdge);
         }
 
-		public void Dispose()
-		{
-			Debug.Assert(_world._lock == false);
-			// shapes and joints are destroyed in World.Destroy
-		}
-
 		/// <summary>
 		/// Creates a shape and attach it to this body.
 		/// @warning This function is locked during callbacks.
 			}
 
 			Shape s = Shape.Create(shapeDef);
-
-			s.Next = _shapeList;
-			_shapeList = s;
-			++_shapeCount;
-
+            _shapeList.AddLast(s);
 			s.Body = this;
 
 			// Add the shape to the world's broad-phase.
 			Debug.Assert(shape.Body == this);
 			shape.DestroyProxy(_world._broadPhase);
 
-			Debug.Assert(_shapeCount > 0);
-			Shape node = _shapeList;
-			bool found = false;
-			while (node != null)
-			{
-				if (node == shape)
-				{
-					_shapeList = shape.Next;
-					found = true;
-					break;
-				}
-
-				node = node.Next;
-			}
-
-			// You tried to remove a shape that is not attached to this body.
-			Debug.Assert(found);
+            bool found = _shapeList.Remove(shape);
+            
+            // You tried to remove a shape that is not attached to this body.
+            Debug.Assert(found);
+			
 
 			shape.Body = null;
-			shape.Next = null;
-
-			--_shapeCount;
 
 			Shape.Destroy(shape);
 		}
             _sweep.C0 = _sweep.C; 
 
 			// Update the sweep radii of all child shapes.
-			for (Shape s = _shapeList; s != null; s = s.Next)
+			foreach (Shape s in _shapeList)
 			{
 				s.UpdateSweepRadius(_sweep.LocalCenter);
 			}
 			// If the body type changed, we need to refilter the broad-phase proxies.
 			if (oldType != _type)
 			{
-				for (Shape s = _shapeList; s!=null; s = s.Next)
+				foreach (Shape s in _shapeList)
 				{
 					s.RefilterProxy(_world._broadPhase, _xf);
 				}
 			_invI = 0.0f;
 
 			Vector2 center = Vector2.Zero;
-			for (Shape s = _shapeList; s!=null; s = s.Next)
+			foreach (Shape s in _shapeList)
 			{
 				MassData massData;
 				s.ComputeMass(out massData);
             _sweep.C0 = _sweep.C; 
 
 			// Update the sweep radii of all child shapes.
-			for (Shape s = _shapeList; s != null; s = s.Next)
+			foreach (Shape s in _shapeList)
 			{
 				s.UpdateSweepRadius(_sweep.LocalCenter);
 			}
 			// If the body type changed, we need to refilter the broad-phase proxies.
 			if (oldType != _type)
 			{
-				for (Shape s = _shapeList; s!=null; s = s.Next)
+				foreach (Shape s in _shapeList)
 				{
 					s.RefilterProxy(_world._broadPhase, _xf);
 				}
 			_sweep.A0 = _sweep.A = angle;
 
 			bool freeze = false;
-			for (Shape s = _shapeList; s != null; s = s.Next)
+			foreach (Shape s in _shapeList)
 			{
 				bool inRange = s.Synchronize(_world._broadPhase, _xf, _xf);
 
 				_flags |= BodyFlags.Frozen;
                 _linearVelocity = Vector2.Zero;
 				_angularVelocity = 0.0f;
-				for (Shape s = _shapeList; s != null; s = s.Next)
+				foreach (Shape s in _shapeList)
 				{
 					s.DestroyProxy(_world._broadPhase);
 				}
 		/// Get the list of all shapes attached to this body.
 		/// </summary>
 		/// <returns></returns>
-		public Shape GetShapeList()
+		public LinkedList<Shape> GetShapeList()
 		{
 			return _shapeList;
 		}
 			XForm xf1 = new XForm(_sweep.C0 - Box2DMath.Mul(rot, _sweep.LocalCenter), rot);
 			
 			bool inRange = true;
-			for (Shape s = _shapeList; s != null; s = s.Next)
+			foreach (Shape s in _shapeList)
 			{
 				inRange = s.Synchronize(_world._broadPhase, xf1, _xf);
 				if (inRange == false)
 				_flags |= BodyFlags.Frozen;
 				_linearVelocity = Vector2.Zero;
 				_angularVelocity = 0.0f;
-				for (Shape s = _shapeList; s != null; s = s.Next)
+				foreach (Shape s in _shapeList)
 				{
 					s.DestroyProxy(_world._broadPhase);
 				}

File src/Dynamics/Controllers/BuoyancyController.cs

                 Vector2 massc = Vector2.Zero;
 				float area = 0;
 				float mass = 0;
-				for (Shape shape = body.GetShapeList(); shape != null; shape = shape.Next)
+				foreach (Shape shape in body.GetShapeList())
 				{
                     Vector2 sc;
 					float sarea = shape.ComputeSubmergedArea(normal, offset, body.XForm, out sc);

File src/Dynamics/World.cs

 
 			// Delete the attached shapes. This destroys broad-phase
 			// proxies and pairs, leading to the destruction of contacts.
-			Shape s = null;
-			if (b._shapeList != null)
-				s = b._shapeList;
-			while (s != null)
+			while (b._shapeList.Count > 0)
 			{
-				Shape s0 = s;
-				s = s.Next;
-
-				if (_destructionListener != null)
+                Shape s0 = b._shapeList.First.Value;
+                if (_destructionListener != null)
 				{
 					_destructionListener.SayGoodbye(s0);
 				}
 
 				s0.DestroyProxy(_broadPhase);
-				Shape.Destroy(s0);
+
+                b._shapeList.RemoveFirst();
 			}
 
 			// Remove world body list.
             _bodyList.Remove(b);
-
-            IDisposable disposeBody = b as IDisposable;
-            if (disposeBody != null)
-                disposeBody.Dispose();
 		}
 
 		/// <summary>
 			if (def.CollideConnected == false)
 			{
 				// Reset the proxies on the body with the minimum number of shapes.
-				Body b = def.Body1._shapeCount < def.Body2._shapeCount ? def.Body1 : def.Body2;
-				for (Shape s = b._shapeList; s != null; s = s.Next)
+                Body b = def.Body1._shapeList.Count < def.Body2._shapeList.Count ? def.Body1 : def.Body2;
+				foreach (Shape s in b._shapeList)
 				{
 					s.RefilterProxy(_broadPhase, b.XForm);
 				}
 			if (collideConnected == false)
 			{
 				// Reset the proxies on the body with the minimum number of shapes.
-				Body b = body1._shapeCount < body2._shapeCount ? body1 : body2;
-				for (Shape s = b._shapeList; s != null; s = s.Next)
+                Body b = body1._shapeList.Count < body2._shapeList.Count ? body1 : body2;
+                foreach (Shape s in b._shapeList)
 				{
 					s.RefilterProxy(_broadPhase, b.XForm);
 				}
 				foreach (Body b in _bodyList)
 				{
 					XForm xf = b.XForm;
-					for (Shape s = b.GetShapeList(); s != null; s = s.Next)
+					foreach (Shape s in b.GetShapeList())
 					{
 						if (b.IsStatic())
 						{
 				foreach (Body b in _bodyList)
 				{
 					XForm xf = b.XForm;
-					for (Shape s = b.GetShapeList(); s != null; s = s.Next)
+					foreach (Shape s in b.GetShapeList())
 					{
 						if (s.Type != ShapeType.PolygonShape)
 						{