/******************************************************************************* * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package hr.fer.zemris.vhdllab.applets.editor.newtb.model.signals; import hr.fer.zemris.vhdllab.applets.editor.newtb.enums.VectorDirection; import hr.fer.zemris.vhdllab.applets.editor.newtb.exceptions.UniformSignalChangeException; import hr.fer.zemris.vhdllab.applets.editor.newtb.exceptions.UniformSignalException; import hr.fer.zemris.vhdllab.applets.editor.newtb.listeners.SignalChangeListener; import java.util.List; import java.util.Map; import java.util.TreeMap; /** * * @author Davor Jurisic * */ public class VectorSignal extends EditableSignal { protected VectorDirection direction = null; public VectorSignal(String name, short dimension, VectorDirection direction) throws UniformSignalException { this(name, dimension, direction, null); } public VectorSignal(String name, short dimension, VectorDirection direction, SignalChangeListener listener) throws UniformSignalException { super(name, dimension, listener); if(direction == null) throw new UniformSignalException("Direction ne smije biti null"); this.direction = direction; } public VectorDirection getDirection() { return direction; } public void deleteSignalChangeValues(int componentIndex) throws UniformSignalException, UniformSignalChangeException { if(componentIndex < 0 || componentIndex >= this.dimension) { throw new UniformSignalException("componentIndex ne odgovara dimenziji signala."); } if(this.signalChangeListener != null) { this.signalChangeListener.suspendSignalChangedEvents(); } for(SignalChange sc : this.changes.values()) { StringBuilder sb = new StringBuilder(sc.getSignalValue()); sb.setCharAt(componentIndex, '0'); sc.setSignalValue(sb.toString()); } this.optimizeSignalChangeValues(); if(this.signalChangeListener != null) { this.signalChangeListener.resumeSignalChangedEvents(); } } public void setSignalChangeValue(long time, String signalValue, int componentIndex) throws UniformSignalChangeException, UniformSignalException { if(componentIndex < 0 || componentIndex >= this.dimension) { throw new UniformSignalException("componentIndex ne odgovara dimenziji signala."); } if(signalValue.length() != 1) { throw new UniformSignalException("Dimenzija signala mora biti 1."); } boolean resumeBeforeExit = true; if(this.signalChangeListener != null) { resumeBeforeExit = !this.signalChangeListener.signalChangedEventsSuspended(); this.signalChangeListener.suspendSignalChangedEvents(); } while(true) { Map.Entry<Long, SignalChange> p = ((TreeMap <Long, SignalChange>)changes).floorEntry(time - 1); Map.Entry<Long, SignalChange> n = ((TreeMap <Long, SignalChange>)changes).ceilingEntry(time + 1); SignalChange prev = p == null ? null : p.getValue(); SignalChange next = n == null ? null : n.getValue(); String newSignalValue = null; if (this.changes.containsKey(new Long(time))) { SignalChange sc = this.changes.get(new Long(time)); StringBuilder sb = new StringBuilder(sc.getSignalValue()); sb.setCharAt(componentIndex, signalValue.charAt(0)); newSignalValue = sb.toString(); sc.setSignalValue(newSignalValue); } else { if(p == null) { StringBuilder sb = new StringBuilder(this.dimension); for(int i = 0; i < this.dimension; i++) { if(i == componentIndex) sb.append(signalValue.charAt(0)); else sb.append('0'); } newSignalValue = sb.toString(); } else { StringBuilder sb = new StringBuilder(p.getValue().getSignalValue()); sb.setCharAt(componentIndex, signalValue.charAt(0)); newSignalValue = sb.toString(); } this.changes.put(Long.valueOf(time), new SignalChange(this.dimension, newSignalValue, time, this)); if (this.signalChangeListener != null) { this.signalChangeListener.signalChanged(this); } } if (prev != null && prev.getSignalValue().equals(newSignalValue)){ this.changes.remove(time); } if (next != null && newSignalValue.equals(next.getSignalValue())) { this.changes.remove(next.getTime()); } n = ((TreeMap <Long, SignalChange>)changes).ceilingEntry(time + 1); next = n == null ? null : n.getValue(); if(next != null && next.getSignalValue().charAt(componentIndex) != signalValue.charAt(0)) { time = next.getTime(); } else { break; } } if(this.signalChangeListener != null && resumeBeforeExit) { this.signalChangeListener.resumeSignalChangedEvents(); } } public void setSignalChangeValue(List<SignalChange> signalChangeList, int componentIndex) throws UniformSignalChangeException, UniformSignalException { if(signalChangeList == null) throw new UniformSignalException("signalChangeList ne smije biti null!"); if(componentIndex < 0 || componentIndex >= this.dimension) { throw new UniformSignalException("componentIndex ne odgovara dimenziji signala."); } try { if(this.signalChangeListener != null) { this.signalChangeListener.suspendSignalChangedEvents(); } for(SignalChange sc : signalChangeList) { this.setSignalChangeValue(sc.getTime(), sc.getSignalValue(), componentIndex); } } catch (UniformSignalChangeException e) { throw e; } finally { if(this.signalChangeListener != null) { this.signalChangeListener.resumeSignalChangedEvents(); } } } public ScalarSignal[] getSignalComponents() throws UniformSignalException, UniformSignalChangeException { ScalarSignal[] resultList = new ScalarSignal[this.dimension]; char[] lastValue = new char[this.dimension]; String sn = null; for(int i = 0; i < this.dimension; i++) { if(this.direction == VectorDirection.to) { sn = this.name + " [" + i + "]"; } else { sn = this.name + " [" + (this.dimension - i - 1) + "]"; } resultList[i] = new ScalarSignal(sn); lastValue[i] = 0; } for(SignalChange sc : this) { for(int i = 0; i < this.dimension; i++) { char c = sc.getSignalValue().charAt(i); if(lastValue[i] == 0) { // Sve je to zbog xilinixa //resultList[this.dimension - i - 1].setSignalChangeValue(sc.getTime(), Character.toString(c)); resultList[i].setSignalChangeValue(sc.getTime(), Character.toString(c)); lastValue[i] = c; } else if(lastValue[i] != c) { // Sve je to zbog xilinixa //resultList[this.dimension - i - 1].setSignalChangeValue(sc.getTime(), Character.toString(c)); resultList[i].setSignalChangeValue(sc.getTime(), Character.toString(c)); lastValue[i] = c; } } } return resultList; } }