package com.indignado.logicbricks.systems.sensors; import com.badlogic.ashley.core.Component; import com.badlogic.ashley.core.ComponentMapper; import com.badlogic.ashley.core.Entity; import com.badlogic.ashley.core.Family; import com.badlogic.gdx.utils.ObjectSet; import com.indignado.logicbricks.components.StateComponent; import com.indignado.logicbricks.components.sensors.SensorComponent; import com.indignado.logicbricks.config.Settings; import com.indignado.logicbricks.core.data.LogicBrick.BrickMode; import com.indignado.logicbricks.core.sensors.DelaySensor; import com.indignado.logicbricks.core.sensors.Sensor; import com.indignado.logicbricks.core.sensors.Sensor.Pulse; import com.indignado.logicbricks.core.sensors.Sensor.TapMode; import com.indignado.logicbricks.systems.LogicBrickSystem; import com.indignado.logicbricks.utils.Log; /** * @author Rubentxu. */ public abstract class SensorSystem<S extends Sensor, SC extends SensorComponent> extends LogicBrickSystem { protected ComponentMapper<SC> sensorMapper; protected ComponentMapper<StateComponent> stateMapper; public SensorSystem(Class<SC> clazz) { super(Family.all(clazz, StateComponent.class).get(), 1); this.sensorMapper = ComponentMapper.getFor(clazz); stateMapper = ComponentMapper.getFor(StateComponent.class); Log.debug(tag, "Create system family %s", clazz.getSimpleName()); } public SensorSystem(Class<SC> clazz, Class<? extends Component> clazz2) { super(Family.all(clazz, clazz2, StateComponent.class).get(), 1); this.sensorMapper = ComponentMapper.getFor(clazz); stateMapper = ComponentMapper.getFor(StateComponent.class); Log.debug("Create system family %s and %s", clazz.getSimpleName(), clazz2.getSimpleName()); } @Override public void update(float deltaTime) { super.update(deltaTime); } public void processEntity(Entity entity, float deltaTime) { if (Settings.DEBUG_ENTITY != null) tag = Log.tagEntity(this.getClass().getSimpleName(), entity); Integer state = stateMapper.get(entity).getCurrentState(); ObjectSet<S> sensors = (ObjectSet<S>) sensorMapper.get(entity).sensors.get(state); if (sensors != null) { for (S sensor : sensors) { boolean doDispatch = false, freqDispatch = false; if (stateMapper.get(entity).isChanged) { Log.debug(tag, "reset firstExec state %d", state); sensor.firstExec = true; sensor.positive = false; sensor.firstTap = Sensor.TapMode.TAP_IN; if (sensor instanceof DelaySensor) { ((DelaySensor) sensor).time = 0; Log.debug(tag, "reset delaysensor time %f", ((DelaySensor) sensor).time); } } boolean processPulseState = false; boolean lastPulse = sensor.positive; sensor.positive = query(sensor, deltaTime); if (sensor.invert) sensor.positive = !sensor.positive; if (sensor.firstExec || ((sensor.tick += deltaTime) > sensor.frequency) || sensor.pulse == Pulse.PM_IDLE.getValue() || (lastPulse != sensor.positive)) { processPulseState = true; if (sensor.tick > sensor.frequency) freqDispatch = true; sensor.tick = 0; } if (processPulseState) { if (sensor.pulse == Pulse.PM_IDLE.getValue()) { doDispatch = lastPulse != sensor.positive; } else { if (Pulse.isPositivePulseMode(sensor)) { doDispatch = (lastPulse != sensor.positive) || sensor.positive; } if (Pulse.isNegativePulseMode(sensor)) { doDispatch = (lastPulse != sensor.positive) || !sensor.positive; } } } if (sensor.tap) { processPulseState = sensor.positive; doDispatch = false; sensor.pulseState = BrickMode.BM_OFF; if (sensor.firstTap == TapMode.TAP_IN && processPulseState) { doDispatch = true; sensor.positive = true; sensor.pulseState = BrickMode.BM_ON; sensor.firstTap = TapMode.TAP_OUT; sensor.lastTap = TapMode.TAP_IN; } else if (sensor.lastTap == TapMode.TAP_IN) { sensor.positive = false; doDispatch = true; if (Pulse.isPositivePulseMode(sensor)) sensor.firstTap = TapMode.TAP_IN; sensor.lastTap = TapMode.TAP_OUT; } else { sensor.positive = false; if (!processPulseState) sensor.firstTap = TapMode.TAP_IN; } } else sensor.pulseState = isPositive(sensor) ? BrickMode.BM_ON : BrickMode.BM_OFF; if (sensor.firstExec) { sensor.firstExec = false; } // Dispatch results if (doDispatch) { sensor.pulseState = BrickMode.BM_ON; } if (!doDispatch && Pulse.isPositivePulseMode(sensor) && sensor.positive && freqDispatch) { sensor.pulseState = BrickMode.BM_ON; } else if (!doDispatch) { sensor.pulseState = BrickMode.BM_OFF; } } } } protected abstract boolean query(S sensor, float deltaTime); protected boolean isPositive(S sensor) { boolean result = sensor.positive; if (sensor.invert) { if (!(sensor.tap && !(Pulse.isPositivePulseMode(sensor)))) result = !result; } return result; } }