private void invalidate(Rect rect, final SceneGraph result) { if (rect == null) { rect = this.top.getBounds(); } this.execute(rect, new InvalidateExecutor(result)); for (OTFDataReader element : this.additionalElements) { element.invalidate(result); } }
@Override public void execute(final double x, final double y, final OTFDataReader reader) { // I the end, the readers are stored in the leaves of the quad tree, and the "mechanics" will // get them out and // feed them into this method here. // The original filling happens via the quadtree "put" method. Technically, this is achieved // (I think) // by ConvertToClientExecutor in a ServerQuad. I.e. the writers in the ServerQuad are // mirrored by the // corresponding readers in the ClientQuad. kai, feb'11 try { if (this.readConst) reader.readConstData(this.in); else reader.readDynData(this.in, this.graph); } catch (IOException e) { throw new RuntimeException(e); } }
public synchronized void getConstData() { byte[] bbyte = this.host.getQuadConstStateBuffer(); ByteBuffer in = ByteBuffer.wrap(bbyte); for (OTFDataReader reader : this.values()) { try { reader.readConstData(in); } catch (IOException e) { e.printStackTrace(); } } for (OTFDataReader reader : this.additionalElements) { try { reader.readConstData(in); } catch (IOException e) { e.printStackTrace(); } } log.info(" read constant data"); }
/** * I think that this requests the scene graph for a given time step and for the rectangle that is * visible. */ private SceneGraph createSceneGraph(final int time, Rect rect) { List<Rect> rects = new LinkedList<>(); /* * This hack ensures that vehicles on links are drawn even if their center is not visible */ if (OTFClientControl.getInstance().getOTFVisConfig().isScaleQuadTreeRect()) { rect = rect.scale(5.0, 5.0); } SceneGraph cachedResult = this.cachedTimes.get(time); // cachedTimes refers to snapshots that were already rendered at some earlier time (only mvi // mode). if (cachedResult != null) { Rect cachedRect = cachedResult.getRect(); if ((cachedRect == null) || cachedRect.containsOrEquals(rect)) return cachedResult; Rect intersec = rect.intersection(cachedRect); if (intersec == null) { // we need to get the whole rect cachedResult = null; } else { // As we can only store ONE rect with our cached Drawing, we cannot simply // add the new portion to the old rect but have to use a rect where both // old and new rect fit into aka the union of both rect = rect.union(cachedRect); // Check the four possible rects, that need filling, possible rect follow this scheme // 1133333344 // 11iiiiii44 // 11iiiiii44 // 1122222244 double r1w = cachedRect.minX - rect.minX; double r2h = cachedRect.minY - rect.minY; double r3h = rect.maxY - cachedRect.maxY; double r4w = rect.maxX - cachedRect.maxX; if (r1w > 0) rects.add(new Rect(rect.minX, rect.minY, cachedRect.minX, rect.maxY)); if (r4w > 0) rects.add(new Rect(cachedRect.maxX, rect.minY, rect.maxX, rect.maxY)); if (r2h > 0) rects.add(new Rect(cachedRect.minX, rect.minY, cachedRect.maxX, cachedRect.minY)); if (r3h > 0) rects.add(new Rect(cachedRect.minX, cachedRect.maxY, cachedRect.maxX, rect.maxY)); } } // otherwise this Scenegraph is not useful, so we create a new one // // I don't understand the above comment. "isLive" means is interactive. if it is not // interactive, there // is no cached result. if (this.host.isLive() == false) { rect = null; cachedResult = null; } SceneGraph result; if (cachedResult == null) { result = new SceneGraph(rect); // (sets up the layers but does not put content) QuadTree.Rect bound2 = this.host.isLive() ? rect : this.top.getBounds(); byte[] bbyte; bbyte = this.host.getQuadDynStateBuffer(bound2); // (seems that this contains the whole time step (in binary form)) ByteBuffer in = ByteBuffer.wrap(bbyte); // (converts the byte buffer into an object) this.execute(bound2, new ReadDataExecutor(in, false, result)); // (this is pretty normal, but I still keep forgetting it: The leaves of the QuadTree contain // objects of type // OTFDataReader. The ReadDataExecutor (defined above) uses them to read the data. for (OTFDataReader element : this.additionalElements) { try { element.readDynData(in, result); } catch (IOException e) { e.printStackTrace(); } } // fill with elements // // I don't understand the wording. Why does "invalidate" do a "fill with elements"? invalidate(rect, result); } else { result = cachedResult; result.setRect(rect); for (Rect rectPart : rects) { QuadTree.Rect bound2 = this.host.isLive() ? rectPart : this.top.getBounds(); byte[] bbyte; bbyte = this.host.getQuadDynStateBuffer(bound2); ByteBuffer in = ByteBuffer.wrap(bbyte); this.execute(bound2, new ReadDataExecutor(in, false, result)); // fill with elements invalidate(rectPart, result); } } result.finish(); if (this.host.isLive() == false) { this.cachedTimes.put(time, result); } return result; }
@Override public void execute(final double x, final double y, final OTFDataReader reader) { reader.invalidate(this.sceneGraph); }