M src/main/net/dermetfan/kryonet/box2d/multiplayer/proposing/ProposingBody.java +17 -8
@@ 43,7 43,7 @@ public class ProposingBody implements Po
private Body body;
private int objectHash;
- private final Callback callback = new Callback() {
+ private final Callback createFixtureCllback = new Callback() {
private final WorldUpdater.Listener resultUpdater = new WorldUpdater.Listener.Adapter() {
@Override
public void created(Fixture fixture, FixtureCreation creation) {
@@ 75,14 75,15 @@ public class ProposingBody implements Po
objectHash = 0;
}
- public Fixture createFixture(FixtureDef def) {
+ public ProposingFixture createFixture(FixtureDef def) {
FixtureCreation creation = Pools.obtain(FixtureCreation.class);
- creation.setObjectHash((int) System.nanoTime()); // FIXME proper hash?
+ int hash = (int) System.nanoTime(); // FIXME proper hash?
+ creation.setObjectHash(hash);
creation.setBodyHash(objectHash);
creation.setFixtureDef(def);
resultFixture = null;
- boolean accepted = world.proposeBlocking(creation, world.getConnection(), callback);
+ boolean accepted = world.proposeBlocking(creation, world.getConnection(), createFixtureCllback);
assert resultFixture != null == accepted;
Pools.free(creation);
@@ 90,16 91,17 @@ public class ProposingBody implements Po
if(!accepted)
return null;
- // TODO ProposingFixture
- return resultFixture;
+ ProposingFixture fixture = world.fixturePool.obtain();
+ fixture.init(this, resultFixture, hash);
+ return fixture;
}
- public Fixture createFixture(Shape shape, float density) {
+ public ProposingFixture createFixture(Shape shape, float density) {
FixtureDef fixtureDef = Pools.obtain(FixtureDef.class);
reset(fixtureDef);
fixtureDef.shape = shape;
fixtureDef.density = density;
- Fixture fixture = createFixture(fixtureDef);
+ ProposingFixture fixture = createFixture(fixtureDef);
reset(fixtureDef);
Pools.free(fixtureDef);
return fixture;
@@ 116,6 118,13 @@ public class ProposingBody implements Po
def.filter.groupIndex = 0;
}
+ public boolean destroyFixture(ProposingFixture fixture) {
+ boolean destroyed = destroyFixture(fixture.getFixture());
+ if(destroyed)
+ world.fixturePool.free(fixture);
+ return destroyed;
+ }
+
public boolean destroyFixture(Fixture fixture) {
return world.destroyObject(fixture);
}
A => src/main/net/dermetfan/kryonet/box2d/multiplayer/proposing/ProposingFixture.java +189 -0
@@ 0,0 1,189 @@
+package net.dermetfan.kryonet.box2d.multiplayer.proposing;
+
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.physics.box2d.Filter;
+import com.badlogic.gdx.physics.box2d.Fixture;
+import com.badlogic.gdx.physics.box2d.Shape;
+import com.badlogic.gdx.physics.box2d.Shape.Type;
+import com.badlogic.gdx.utils.Pool.Poolable;
+import com.badlogic.gdx.utils.Pools;
+import net.dermetfan.gdx.physics.box2d.Box2DUtils;
+import net.dermetfan.gdx.physics.box2d.WorldObserver.FixtureChange;
+import net.dermetfan.kryonet.box2d.multiplayer.packets.updates.Change;
+
+public class ProposingFixture implements Poolable {
+
+ private final ProposingWorld world;
+ private ProposingBody body;
+
+ private Fixture fixture;
+ private int objectHash;
+
+ ProposingFixture(ProposingWorld world) {
+ this.world = world;
+ }
+
+ void init(ProposingBody body, Fixture fixture, int objectHash) {
+ this.body = body;
+ this.fixture = fixture;
+ this.objectHash = objectHash;
+ }
+
+ @Override
+ public void reset() {
+ body = null;
+ fixture = null;
+ objectHash = 0;
+ }
+
+ public boolean setDensity(float density) {
+ if(density == fixture.getDensity())
+ return true;
+
+ FixtureChange change = Pools.obtain(FixtureChange.class);
+ change.newDensity = density;
+
+ @SuppressWarnings("unchecked")
+ Change<Fixture> update = Pools.obtain(Change.class);
+ update.setObjectHash(objectHash);
+ update.setChange(change);
+
+ boolean accepted = world.proposeBlocking(update, world.getConnection());
+
+ Pools.free(change);
+ Pools.free(update);
+
+ if(accepted)
+ fixture.setDensity(density);
+ return accepted;
+ }
+
+ public boolean setRestitution(float restitution) {
+ if(restitution == fixture.getRestitution())
+ return true;
+
+ FixtureChange change = Pools.obtain(FixtureChange.class);
+ change.newRestitution = restitution;
+
+ @SuppressWarnings("unchecked")
+ Change<Fixture> update = Pools.obtain(Change.class);
+ update.setObjectHash(objectHash);
+ update.setChange(change);
+
+ boolean accepted = world.proposeBlocking(update, world.getConnection());
+
+ Pools.free(change);
+ Pools.free(update);
+
+ if(accepted)
+ fixture.setRestitution(restitution);
+ return accepted;
+ }
+
+ public boolean setSensor(boolean sensor) {
+ if(sensor == fixture.isSensor())
+ return true;
+
+ FixtureChange change = Pools.obtain(FixtureChange.class);
+ change.newSensor = sensor;
+
+ @SuppressWarnings("unchecked")
+ Change<Fixture> update = Pools.obtain(Change.class);
+ update.setObjectHash(objectHash);
+ update.setChange(change);
+
+ boolean accepted = world.proposeBlocking(update, world.getConnection());
+
+ Pools.free(change);
+ Pools.free(update);
+
+ if(accepted)
+ fixture.setSensor(sensor);
+ return accepted;
+ }
+
+ public boolean setFriction(float friction) {
+ if(friction == fixture.getFriction())
+ return true;
+
+ FixtureChange change = Pools.obtain(FixtureChange.class);
+ change.newFriction = friction;
+
+ @SuppressWarnings("unchecked")
+ Change<Fixture> update = Pools.obtain(Change.class);
+ update.setObjectHash(objectHash);
+ update.setChange(change);
+
+ boolean accepted = world.proposeBlocking(update, world.getConnection());
+
+ Pools.free(change);
+ Pools.free(update);
+
+ if(accepted)
+ fixture.setFriction(friction);
+ return accepted;
+ }
+
+ public boolean setFilterData(Filter filter) {
+ if(Box2DUtils.equals(filter, fixture.getFilterData()))
+ return true;
+
+ FixtureChange change = Pools.obtain(FixtureChange.class);
+ change.newFilter = filter;
+
+ @SuppressWarnings("unchecked")
+ Change<Fixture> update = Pools.obtain(Change.class);
+ update.setObjectHash(objectHash);
+ update.setChange(change);
+
+ boolean accepted = world.proposeBlocking(update, world.getConnection());
+
+ Pools.free(change);
+ Pools.free(update);
+
+ if(accepted)
+ fixture.setFilterData(filter);
+ return accepted;
+ }
+
+ // local delegates
+
+ public Type getType() {return fixture.getType();}
+
+ public float getDensity() {return fixture.getDensity();}
+
+ public float getRestitution() {return fixture.getRestitution();}
+
+ public boolean isSensor() {return fixture.isSensor();}
+
+ public float getFriction() {return fixture.getFriction();}
+
+ public Object getUserData() {return fixture.getUserData();}
+
+ public void setUserData(Object userData) {fixture.setUserData(userData);}
+
+ public Filter getFilterData() {return fixture.getFilterData();}
+
+ public Shape getShape() {return fixture.getShape();}
+
+ public void refilter() {fixture.refilter();}
+
+ public boolean testPoint(float x, float y) {return fixture.testPoint(x, y);}
+
+ public boolean testPoint(Vector2 p) {return fixture.testPoint(p);}
+
+ // getters and setters
+
+ public ProposingBody getBody() {
+ return body;
+ }
+
+ public Fixture getFixture() {
+ return fixture;
+ }
+
+ public int getObjectHash() {
+ return objectHash;
+ }
+
+}
M src/main/net/dermetfan/kryonet/box2d/multiplayer/proposing/ProposingWorld.java +7 -2
@@ 97,6 97,13 @@ public class ProposingWorld extends Upda
}
};
+ final Pool<ProposingFixture> fixturePool = new Pool<ProposingFixture>(5, 250) {
+ @Override
+ protected ProposingFixture newObject() {
+ return new ProposingFixture(ProposingWorld.this);
+ }
+ };
+
/** @see #ProposingWorld(World, DualIntMap, Connection) */
public ProposingWorld(World world, DualIntMap<Object> index) {
this.world = world;
@@ 110,8 117,6 @@ public class ProposingWorld extends Upda
setConnection(connection);
}
- // requires proposal
-
public ProposingBody createBody(BodyDef def) {
BodyCreation creation = Pools.obtain(BodyCreation.class);
int hash = (int) System.nanoTime(); // FIXME proper hash?