diff options
author | chai <chaifix@163.com> | 2018-09-05 22:41:32 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-09-05 22:41:32 +0800 |
commit | b9869110af91ad5ed8fe01e39651462b879b04ef (patch) | |
tree | 6cf7e674649d277fab8d0b4896d5438a08958ad2 /Box2d/Assets/Program/Box2d/Dynamics/Controllers/Controller.cs | |
parent | 1db41995703f17069c27f9eebefda4c6858782ec (diff) |
*update
Diffstat (limited to 'Box2d/Assets/Program/Box2d/Dynamics/Controllers/Controller.cs')
-rw-r--r-- | Box2d/Assets/Program/Box2d/Dynamics/Controllers/Controller.cs | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/Box2d/Assets/Program/Box2d/Dynamics/Controllers/Controller.cs b/Box2d/Assets/Program/Box2d/Dynamics/Controllers/Controller.cs new file mode 100644 index 0000000..26bfbdf --- /dev/null +++ b/Box2d/Assets/Program/Box2d/Dynamics/Controllers/Controller.cs @@ -0,0 +1,174 @@ +using System; + +namespace Box2DX.Dynamics.Controllers +{ + /// <summary> + /// A controller edge is used to connect bodies and controllers together + /// in a bipartite graph. + /// </summary> + public class ControllerEdge + { + public Controller controller; // provides quick access to other end of this edge. + public Body body; // the body + public ControllerEdge prevBody; // the previous controller edge in the controllers's joint list + public ControllerEdge nextBody; // the next controller edge in the controllers's joint list + public ControllerEdge prevController; // the previous controller edge in the body's joint list + public ControllerEdge nextController; // the next controller edge in the body's joint list + } + + /// <summary> + /// Base class for controllers. Controllers are a convience for encapsulating common + /// per-step functionality. + /// </summary> + public abstract class Controller : IDisposable + { + internal Controller _prev; + internal Controller _next; + + internal World _world; + protected ControllerEdge _bodyList; + protected int _bodyCount; + + public Controller() + { + _bodyList = null; + _bodyCount = 0; + } + + public Controller(World world) + { + _bodyList = null; + _bodyCount = 0; + + _world = world; + } + + public void Dispose() + { + //Remove attached bodies + + //Previus implementation: + //while (_bodyCount > 0) + // RemoveBody(_bodyList.body); + + Clear(); + } + + /// <summary> + /// Controllers override this to implement per-step functionality. + /// </summary> + public abstract void Step(TimeStep step); + + /// <summary> + /// Controllers override this to provide debug drawing. + /// </summary> + public virtual void Draw(DebugDraw debugDraw) { } + + /// <summary> + /// Adds a body to the controller list. + /// </summary> + public void AddBody(Body body) + { + ControllerEdge edge = new ControllerEdge(); + + edge.body = body; + edge.controller = this; + + //Add edge to controller list + edge.nextBody = _bodyList; + edge.prevBody = null; + if (_bodyList != null) + _bodyList.prevBody = edge; + _bodyList = edge; + ++_bodyCount; + + //Add edge to body list + edge.nextController = body._controllerList; + edge.prevController = null; + if (body._controllerList != null) + body._controllerList.prevController = edge; + body._controllerList = edge; + } + + /// <summary> + /// Removes a body from the controller list. + /// </summary> + public void RemoveBody(Body body) + { + //Assert that the controller is not empty + Box2DXDebug.Assert(_bodyCount > 0); + + //Find the corresponding edge + ControllerEdge edge = _bodyList; + while (edge != null && edge.body != body) + edge = edge.nextBody; + + //Assert that we are removing a body that is currently attached to the controller + Box2DXDebug.Assert(edge != null); + + //Remove edge from controller list + if (edge.prevBody != null) + edge.prevBody.nextBody = edge.nextBody; + if (edge.nextBody != null) + edge.nextBody.prevBody = edge.prevBody; + if (edge == _bodyList) + _bodyList = edge.nextBody; + --_bodyCount; + + //Remove edge from body list + if (edge.prevController != null) + edge.prevController.nextController = edge.nextController; + if (edge.nextController != null) + edge.nextController.prevController = edge.prevController; + if (edge == body._controllerList) + body._controllerList = edge.nextController; + + //Free the edge + edge = null; + } + + /// <summary> + /// Removes all bodies from the controller list. + /// </summary> + public void Clear() + { +#warning "Check this" + ControllerEdge current = _bodyList; + while (current != null) + { + ControllerEdge edge = current; + + //Remove edge from controller list + _bodyList = edge.nextBody; + + //Remove edge from body list + if (edge.prevController != null) + edge.prevController.nextController = edge.nextController; + if (edge.nextController != null) + edge.nextController.prevController = edge.prevController; + if (edge == edge.body._controllerList) + edge.body._controllerList = edge.nextController; + + //Free the edge + //m_world->m_blockAllocator.Free(edge, sizeof(b2ControllerEdge)); + } + + _bodyCount = 0; + } + + /// <summary> + /// Get the next body in the world's body list. + /// </summary> + internal Controller GetNext() { return _next; } + + /// <summary> + /// Get the parent world of this body. + /// </summary> + internal World GetWorld() { return _world; } + + /// <summary> + /// Get the attached body list + /// </summary> + internal ControllerEdge GetBodyList() { return _bodyList; } + } +}
\ No newline at end of file |