Browse Source

Fix Fixture:getShape. Resolves issue #1319.

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
8ea2f09a1c

+ 37 - 7
src/modules/physics/box2d/Fixture.cpp

@@ -76,9 +76,39 @@ Fixture::~Fixture()
 	delete udata;
 }
 
-Shape::Type Fixture::getType() const
+void Fixture::checkCreateShape()
 {
-	return Shape(fixture->GetShape(), false).getType();
+	if (shape.get() != nullptr || fixture == nullptr || fixture->GetShape() == nullptr)
+		return;
+
+	b2Shape *bshape = fixture->GetShape();
+
+	switch (bshape->GetType())
+	{
+	case b2Shape::e_circle:
+		shape.set(new CircleShape((b2CircleShape *) bshape, false), Acquire::NORETAIN);
+		break;
+	case b2Shape::e_edge:
+		shape.set(new EdgeShape((b2EdgeShape *) bshape, false), Acquire::NORETAIN);
+		break;
+	case b2Shape::e_polygon:
+		shape.set(new PolygonShape((b2PolygonShape *) bshape, false), Acquire::NORETAIN);
+		break;
+	case b2Shape::e_chain:
+		shape.set(new ChainShape((b2ChainShape *) bshape, false), Acquire::NORETAIN);
+		break;
+	default:
+		break;
+	}
+}
+
+Shape::Type Fixture::getType()
+{
+	checkCreateShape();
+	if (shape.get() == nullptr)
+		return Shape::SHAPE_INVALID;
+	else
+		return shape->getType();
 }
 
 void Fixture::setFriction(float friction)
@@ -126,12 +156,10 @@ Body *Fixture::getBody() const
 	return body;
 }
 
-Shape *Fixture::getShape() const
+Shape *Fixture::getShape()
 {
-	if (!fixture->GetShape())
-		return nullptr;
-
-	return new Shape(fixture->GetShape(), false);
+	checkCreateShape();
+	return shape;
 }
 
 bool Fixture::isValid() const
@@ -329,6 +357,8 @@ void Fixture::destroy(bool implicit)
 		return;
 	}
 
+	shape.set(nullptr);
+
 	if (!implicit && fixture != nullptr)
 		body->body->DestroyFixture(fixture);
 	Memoizer::remove(fixture);

+ 7 - 2
src/modules/physics/box2d/Fixture.h

@@ -79,12 +79,12 @@ public:
 	 * Gets the type of the Fixture's Shape. Useful for
 	 * debug drawing.
 	 **/
-	Shape::Type getType() const;
+	Shape::Type getType();
 
 	/**
 	 * Gets the Shape attached to this Fixture.
 	 **/
-	Shape *getShape() const;
+	Shape *getShape();
 
 	/**
 	 * Returns true if the fixture is active in a Box2D world.
@@ -212,9 +212,14 @@ public:
 
 protected:
 
+	void checkCreateShape();
+
 	Body *body;
 	fixtureudata *udata;
 	b2Fixture *fixture;
+
+	StrongRef<Shape> shape;
+
 };
 
 } // box2d

+ 2 - 2
src/modules/physics/box2d/Shape.cpp

@@ -38,7 +38,7 @@ namespace box2d
 {
 
 Shape::Shape()
-	: shape(NULL)
+	: shape(nullptr)
 	, own(false)
 {
 }
@@ -58,7 +58,7 @@ Shape::~Shape()
 		Memoizer::remove(shape);
 		delete shape;
 	}
-	shape = 0;
+	shape = nullptr;
 }
 
 Shape::Type Shape::getType() const

+ 6 - 6
src/modules/physics/box2d/wrap_Fixture.cpp

@@ -118,22 +118,22 @@ int w_Fixture_getBody(lua_State *L)
 int w_Fixture_getShape(lua_State *L)
 {
 	Fixture *t = luax_checkfixture(L, 1);
-	StrongRef<Shape> shape(t->getShape(), Acquire::NORETAIN);
-	if (shape.get() == nullptr)
+	Shape * shape = t->getShape();
+	if (shape == nullptr)
 		return 0;
 	switch (shape->getType())
 	{
 	case Shape::SHAPE_EDGE:
-		luax_pushtype(L, shape);
+		luax_pushtype(L, dynamic_cast<EdgeShape *>(shape));
 		break;
 	case Shape::SHAPE_CHAIN:
-		luax_pushtype(L, shape);
+		luax_pushtype(L, dynamic_cast<ChainShape *>(shape));
 		break;
 	case Shape::SHAPE_CIRCLE:
-		luax_pushtype(L, shape);
+		luax_pushtype(L, dynamic_cast<CircleShape *>(shape));
 		break;
 	case Shape::SHAPE_POLYGON:
-		luax_pushtype(L, shape);
+		luax_pushtype(L, dynamic_cast<PolygonShape *>(shape));
 		break;
 	default:
 		luax_pushtype(L, shape);