package mygraphs; import main.Node; import main.NodeTemplate; import main.Model; import main.Cell; import main.Globals; import iterators.MultiFloatReturn; import java.awt.event.*; import java.awt.*; class NodeValueStorage implements ActionListener { int itsCellNum; String itsNodeName; Node itsNode; int numStoragePts = 1000; float [] times = new float[numStoragePts]; float [] values = new float[numStoragePts]; int firstPt = 0, lastPt = 0; /** Used to scan through all the points stored in the graph in order. */ int scannerPt = 0; /** Modes used in getValue(). */ public final static int FROM_BEGIN = 1, FROM_END = 2; public NodeValueStorage(Cell cell, Node node, Model model) { itsCellNum = cell.getItsNum(); itsNodeName = ((NodeTemplate)model.net.getNodes().elementAt(node.getNodeNum())).getName(); itsNode = node; reset(); } public void storeCurrentValue() { lastPt++; if(lastPt >= numStoragePts) lastPt = 0; if(lastPt == firstPt) firstPt++; if(firstPt >= numStoragePts) firstPt = 0; times[lastPt] = Globals.time; values[lastPt] = itsNode.getSum(); } public float getValue(float time) { if(time < times[firstPt] || time > times[lastPt]) return 0f; // Find the neighboring pts - not very efficient, but oh well int high_pt = firstPt; while(high_pt != lastPt && time > times[high_pt]) { high_pt++; if(high_pt == numStoragePts) high_pt = 0; } int low_pt = high_pt - 1; if(low_pt < 0) low_pt = numStoragePts - 1; float val = (time - times[low_pt]) / (times[high_pt] - times[low_pt]); val = values[low_pt] + val * (values[high_pt] - values[low_pt]); return val; } public MultiFloatReturn getValueRange(float time1, float time2) { // Check to see if the times are outside the array or the same as each other and return something appropriate if(time2 < time1) return new MultiFloatReturn(0f, 0f); else if(time2 == time1) { float val = getValue(time1); return new MultiFloatReturn(val, val); } else if(time2 < times[firstPt] || time1 > times[lastPt]) return new MultiFloatReturn(0f, 0f); // If we get here, then the times requested are within the array of data // Find the neighboring pts - not very efficient, but oh well float min_val = Float.MAX_VALUE; float max_val = -Float.MAX_VALUE; int pt = firstPt; while(pt != lastPt && time1 > times[pt]) { pt++; if(pt == numStoragePts) pt = 0; } float min_value = values[pt]; float max_value = values[pt]; while(pt != lastPt && time2 > times[pt]) { if(values[pt] > max_value) max_value = values[pt]; if(values[pt] < min_value) min_value = values[pt]; pt++; if(pt == numStoragePts) pt = 0; } return new MultiFloatReturn(min_value, max_value); } public void getValue(MultiFloatReturn mfr, int mode, int step) { switch(mode) { case FROM_BEGIN: if(step < 0) { mfr.f1 = 0; mfr.f2 = 0; return; } else if(step >= numStoragePts) { mfr.f1 = 0; mfr.f2 = 0; return; } step = firstPt + step; if(step > numStoragePts) step -= numStoragePts; if(lastPt >= firstPt && step > lastPt) { mfr.f1 = 0; mfr.f2 = 0; return; } mfr.f1 = times[step]; mfr.f2 = values[step]; return; case FROM_END: if(step > 0) { mfr.f1 = 0; mfr.f2 = 0; return; } else if( (-step) >= numStoragePts) { mfr.f1 = 0; mfr.f2 = 0; return; } step = lastPt + step; if(step < 0) step += numStoragePts; if(lastPt >= firstPt && step > lastPt) { mfr.f1 = 0; mfr.f2 = 0; return; } mfr.f1 = times[step]; mfr.f2 = values[step]; return; } } public void reset() { firstPt = 0; lastPt = 0; times[0] = 0; values[0] = 0; } public void resetScanner() { resetScanner(0f); } public void resetScanner(float time) { scannerPt = firstPt; while(scannerPt != lastPt && time > times[scannerPt]) { scannerPt++; if(scannerPt == numStoragePts) scannerPt = 0; } if(scannerPt != lastPt) { scannerPt--; if(scannerPt < 0) scannerPt = numStoragePts - 1; } } /** Returns false if the series pointer has passed the end of the available data, or if the time at the data pointed to by the series pointer is past the input 'time'. */ public boolean hasMorePoints(float time) { if(scannerPt == -1) return false; else if(times[scannerPt] > time) return false; else return true; } /** Returns the time, value of the next point int the series in f1, f2 of the MultiFloatReturn. Also advances the series pointer by one. */ public void getNextPoint(MultiFloatReturn mfr) { mfr.f1 = times[scannerPt]; mfr.f2 = values[scannerPt]; if(scannerPt == lastPt) scannerPt = -1; else scannerPt++; if(scannerPt == numStoragePts) scannerPt = 0; } public void actionPerformed(ActionEvent event) { if((event.getActionCommand()).equals("UpdateCells")) { storeCurrentValue(); } else if((event.getActionCommand()).equals("NewRun")) { reset(); } else if((event.getActionCommand()).equals("SetModel")) { // Reset graph somehow } else if((event.getActionCommand()).equals("SetNetwork")) { // Reset graph somehow } } }