- /*
- * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
- #include "b2Controller.h"
- #include "../../Common/b2BlockAllocator.h"
- b2Controller::~b2Controller()
- {
- //Remove attached bodies
- Clear();
- }
- void b2Controller::AddBody(b2Body* body)
- {
- void* mem = m_world->m_blockAllocator.Allocate(sizeof(b2ControllerEdge));
- b2ControllerEdge* edge = new (mem) b2ControllerEdge;
- edge->body = body;
- edge->controller = this;
- //Add edge to controller list
- edge->nextBody = m_bodyList;
- edge->prevBody = NULL;
- if(m_bodyList)
- m_bodyList->prevBody = edge;
- m_bodyList = edge;
- ++m_bodyCount;
- //Add edge to body list
- edge->nextController = body->m_controllerList;
- edge->prevController = NULL;
- if(body->m_controllerList)
- body->m_controllerList->prevController = edge;
- body->m_controllerList = edge;
- }
- void b2Controller::RemoveBody(b2Body* body)
- {
- //Assert that the controller is not empty
- b2Assert(m_bodyCount>0);
- //Find the corresponding edge
- b2ControllerEdge* edge = m_bodyList;
- while(edge && edge->body!=body)
- edge = edge->nextBody;
- //Assert that we are removing a body that is currently attached to the controller
- b2Assert(edge!=NULL);
- //Remove edge from controller list
- if(edge->prevBody)
- edge->prevBody->nextBody = edge->nextBody;
- if(edge->nextBody)
- edge->nextBody->prevBody = edge->prevBody;
- if(edge == m_bodyList)
- m_bodyList = edge->nextBody;
- --m_bodyCount;
- //Remove edge from body list
- if(edge->prevController)
- edge->prevController->nextController = edge->nextController;
- if(edge->nextController)
- edge->nextController->prevController = edge->prevController;
- if(edge == body->m_controllerList)
- body->m_controllerList = edge->nextController;
- //Free the edge
- m_world->m_blockAllocator.Free(edge, sizeof(b2ControllerEdge));
- }
- void b2Controller::Clear(){
- while(m_bodyList)
- {
- b2ControllerEdge* edge = m_bodyList;
- //Remove edge from controller list
- m_bodyList = edge->nextBody;
- //Remove edge from body list
- if(edge->prevController)
- edge->prevController->nextController = edge->nextController;
- if(edge->nextController)
- edge->nextController->prevController = edge->prevController;
- if(edge == edge->body->m_controllerList)
- edge->body->m_controllerList = edge->nextController;
- //Free the edge
- m_world->m_blockAllocator.Free(edge, sizeof(b2ControllerEdge));
- }
- m_bodyCount = 0;
- }