/******************************************************************************* * Copyright (c) 2003-2005, 2013 Till Zoppke. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Till Zoppke - initial API and implementation ******************************************************************************/ /* * Created on 17.01.2004 * * To change the template for this generated file go to * Window>Preferences>Java>Code Generation>Code and Comments */ package eniac.data.model.parent; import eniac.data.PulseInteractor; import eniac.data.model.Connector; import eniac.data.model.EData; import eniac.data.type.EType; /** * @author zoppke * * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ public class Tray extends ParentData implements PulseInteractor { // number of channels in a tray private static final int NUMBER_OF_CHANNELS = 11; // if we are transmitting a program pulse, this is the index of the // active channel private int _activeIndex; // last time we got a pulse private long _lastPulse = -11; // value of the pulse private long _pulseValue = 0; public Tray() { // empty } // ========================= PulseInteractor methods // ======================== /** * @param time * @param source * @return @see eniac.data.PulseInteractor#canReceiveDigit(long, * eniac.data.PulseInteractor) */ public boolean canReceiveDigit(long time, PulseInteractor source) { // we always can receive a digit, because we won't send any wire twice // receiving is intelligent, that means any wire is checked against // double pulse. return true; } private long checkDigit(long time, long value) { // check, if this is the first pulse within this time slot if (_lastPulse < time) { // adjust pulse time and value _lastPulse = time; _pulseValue = value; } else { // there has been a pulse before. Adjust values long oldPulseValue = _pulseValue; _pulseValue |= value; value = _pulseValue ^ oldPulseValue; } return value; } /** * @param time * @param value * @param source * @see eniac.data.PulseInteractor#receiveDigit(long, int, * eniac.data.PulseInteractor) */ public void receiveDigit(long time, long value, PulseInteractor source) { // if value contains no pulse, return immediately if (value == 0) { return; } // check value value = checkDigit(time, value); // send as digit pulse sendDigit(time, value, this); // send as program pulses for (int i = NUMBER_OF_CHANNELS - 1; i >= 0; --i) { if (value % 10 > 0) { _activeIndex = i; sendProgram(time, this); } value /= 10; } } /** * @param time * @param value * @param source * @see eniac.data.PulseInteractor#sendDigit(long, int, * eniac.data.PulseInteractor) */ public void sendDigit(long time, long value, PulseInteractor source) { EData[] children = getGarten().getKinder(EType.DIGIT_CONNECTOR_CROSS); for (int i = 0; i < children.length; ++i) { Connector c = (Connector) children[i]; c.sendDigit(time, value, this); } } /** * @param time * @return @see eniac.data.PulseInteractor#canReceiveProgram(long) */ public boolean canReceiveProgram(long time, PulseInteractor source) { return true; } /** * @param time * @param source * @see eniac.data.PulseInteractor#receiveProgram(long, * eniac.data.PulseInteractor) */ public void receiveProgram(long time, PulseInteractor source) { _activeIndex = ((EData) source).getIndex() % NUMBER_OF_CHANNELS; long value = (long) Math.pow(10, 10 - _activeIndex); checkDigit(time, value); if (value == 0) { return; } sendProgram(time, this); sendDigit(time, value, this); } /** * @param time * @param source * @see eniac.data.PulseInteractor#sendProgram(long, * eniac.data.PulseInteractor) */ public void sendProgram(long time, PulseInteractor source) { int number = getGarten().getNumber(EType.PROGRAM_CONNECTOR); for (int i = _activeIndex; i < number; i += NUMBER_OF_CHANNELS) { Connector c = (Connector) getGarten().getKind(EType.PROGRAM_CONNECTOR, i); c.sendProgram(time, this); } } }