diff --git a/ashley/src/com/badlogic/ashley/core/Engine.java b/ashley/src/com/badlogic/ashley/core/Engine.java index c195706e..af93a506 100644 --- a/ashley/src/com/badlogic/ashley/core/Engine.java +++ b/ashley/src/com/badlogic/ashley/core/Engine.java @@ -20,6 +20,8 @@ import com.badlogic.ashley.core.SystemManager.SystemListener; import com.badlogic.ashley.signals.Listener; import com.badlogic.ashley.signals.Signal; +import com.badlogic.ashley.systems.InterpolatingSystem; +import com.badlogic.ashley.systems.PhysicsSystem; import com.badlogic.ashley.utils.ImmutableArray; /** @@ -189,6 +191,31 @@ public void update(float deltaTime){ updating = false; } } + + /** + * Updates all registered {@link PhysicsSystem}s. Should be used according to http://gafferongames.com/game-physics/fix-your-timestep/ + * @param physicsStep the physics step to use in the simulation, not the delta time, should be constant + */ + public void updatePhysics(float physicsStep) { + ImmutableArray systems = systemManager.getPhysicsSystems(); + for (PhysicsSystem system : systems) { + system.updatePhysics(physicsStep); + } + } + + /** + * Updates all registered {@link InterpolatingSystem}s. Should be used after a physics simulation with a fixed timestep, + * see http://gafferongames.com/game-physics/fix-your-timestep/ + * @param delta current delta time, sometimes necessary for some rendering + * @param physicsStep the physics step used in the simulation, should be constant + * @param inAccumulator what is left in the accumulator after performing possible physics step, should be < physicsStep + */ + public void interpolate(float delta, float physicsStep, float inAccumulator) { + ImmutableArray systems = systemManager.getInterpolatingSystems(); + for (InterpolatingSystem system : systems) { + system.interpolate(delta, physicsStep, inAccumulator); + } + } protected void addEntityInternal(Entity entity) { entity.componentAdded.add(componentAdded); diff --git a/ashley/src/com/badlogic/ashley/core/SystemManager.java b/ashley/src/com/badlogic/ashley/core/SystemManager.java index a41f514b..9f31339c 100644 --- a/ashley/src/com/badlogic/ashley/core/SystemManager.java +++ b/ashley/src/com/badlogic/ashley/core/SystemManager.java @@ -1,17 +1,21 @@ package com.badlogic.ashley.core; -import java.util.Comparator; - -import com.badlogic.ashley.signals.Listener; -import com.badlogic.ashley.signals.Signal; +import com.badlogic.ashley.systems.InterpolatingSystem; +import com.badlogic.ashley.systems.PhysicsSystem; import com.badlogic.ashley.utils.ImmutableArray; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; +import java.util.Comparator; + class SystemManager { private SystemComparator systemComparator = new SystemComparator(); private Array systems = new Array(false, 16); + private Array physicsSystems = new Array(false, 16); + private Array interpolatingSystems = new Array(false, 16); private ImmutableArray immutableSystems = new ImmutableArray(systems); + private ImmutableArray immutablePhysicsSystems = new ImmutableArray(physicsSystems); + private ImmutableArray immutableInterpolatingSystems = new ImmutableArray(interpolatingSystems); private ObjectMap, EntitySystem> systemsByClass = new ObjectMap, EntitySystem>(); private SystemListener listener; @@ -31,6 +35,13 @@ public void addSystem(EntitySystem system){ systemsByClass.put(systemType, system); systems.sort(systemComparator); listener.systemAdded(system); + + if (system instanceof PhysicsSystem) { + physicsSystems.add((PhysicsSystem) system); + } + if (system instanceof InterpolatingSystem) { + interpolatingSystems.add((InterpolatingSystem) system); + } } public void removeSystem(EntitySystem system){ @@ -38,6 +49,12 @@ public void removeSystem(EntitySystem system){ systemsByClass.remove(system.getClass()); listener.systemRemoved(system); } + if (system instanceof PhysicsSystem) { + physicsSystems.removeValue((PhysicsSystem) system, true); + } + if (system instanceof InterpolatingSystem) { + interpolatingSystems.removeValue((InterpolatingSystem) system, true); + } } @SuppressWarnings("unchecked") @@ -48,6 +65,14 @@ public T getSystem(Class systemType) { public ImmutableArray getSystems() { return immutableSystems; } + + public ImmutableArray getPhysicsSystems() { + return immutablePhysicsSystems; + } + + public ImmutableArray getInterpolatingSystems() { + return immutableInterpolatingSystems; + } private static class SystemComparator implements Comparator{ @Override diff --git a/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java b/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java new file mode 100644 index 00000000..50933891 --- /dev/null +++ b/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java @@ -0,0 +1,19 @@ +package com.badlogic.ashley.systems; + +import com.badlogic.ashley.core.Engine; +import com.badlogic.ashley.core.EntitySystem; + +/** + * An {@link EntitySystem} that is meant to reduce temporal aliasing when using a fixed timestep for physics + * See http://gafferongames.com/game-physics/fix-your-timestep/ for explanation. + */ +public interface InterpolatingSystem { + + /** + * Will be called when {@link Engine#interpolate(float, float, float)} is called. + * @param delta current delta time, sometimes necessary for some rendering + * @param physicsStep the physics step used in the simulation, should be constant + * @param inAccumulator what is left in the accumulator after performing possible physics step, should be < physicsStep + */ + void interpolate(float delta, float physicsStep, float inAccumulator); +} diff --git a/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java b/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java new file mode 100644 index 00000000..296204bb --- /dev/null +++ b/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java @@ -0,0 +1,17 @@ +package com.badlogic.ashley.systems; + +import com.badlogic.ashley.core.Engine; +import com.badlogic.ashley.core.EntitySystem; + +/** + * An {@link EntitySystem} that is meant for operations with a fixed timestep, like physics. + * See http://gafferongames.com/game-physics/fix-your-timestep/ for explanation. + */ +public interface PhysicsSystem { + + /** + * Will be called when {@link Engine#updatePhysics(float)} is called. + * @param physicsStep the physics step to use in the simulation, not the delta time, should be constant + */ + void updatePhysics(float physicsStep); +}