/******************************************************************************* * Copyright (c) 2010 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.databoard.example.old; import java.awt.geom.Rectangle2D; import java.io.IOException; import org.simantics.databoard.Bindings; import org.simantics.databoard.Datatypes; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.RecordBinding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.type.Datatype; /** * {@link Binding} is a link between an instance and a {@link Datatype}. * {@link Datatypes#getContentBinding(Class)} creates binding object which is based on * reflection. Although the performance is good, it can be improved by writing * a taylored binding by hand. *

* The example demonstrates how to write binding to {@link Rectangle2D}. * * @author Toni Kalajainen */ public class BindingExample { static class Rectangle2DBinding extends RecordBinding { public Rectangle2DBinding() { componentBindings = new Binding[4]; componentBindings[0] = Bindings.getBindingUnchecked(Double.class); componentBindings[1] = Bindings.getBindingUnchecked(Double.class); componentBindings[2] = Bindings.getBindingUnchecked(Double.class); componentBindings[3] = Bindings.getBindingUnchecked(Double.class); type = Datatypes.getDatatypeUnchecked( Rectangle2D.Double.class ); } @Override public Object create(Object... value) { return new Rectangle2D.Double((Double)value[0], (Double)value[1], (Double)value[2], (Double)value[3]); } @Override public Object getComponent(Object obj, int index) { Rectangle2D rect = (Rectangle2D) obj; switch (index) { case 0: return rect.getX(); case 1: return rect.getY(); case 2: return rect.getWidth(); case 3: return rect.getHeight(); default: throw new IllegalArgumentException("index out of range, expected 0..3, got "+index); } } @Override public Object createPartial() throws BindingException { return new Rectangle2D.Double(); } @Override public void setComponents(Object obj, Object... value) { Rectangle2D rect = (Rectangle2D) obj; rect.setFrame((Double)value[0], (Double)value[1], (Double)value[2], (Double)value[3]); } @Override public void setComponent(Object obj, int index, Object value) throws BindingException { Rectangle2D rect = (Rectangle2D) obj; switch (index) { case 0: rect.setRect((Double)value, rect.getY(), rect.getWidth(), rect.getHeight()); break; case 1: rect.setRect(rect.getX(), (Double)value, rect.getWidth(), rect.getHeight()); break; case 2: rect.setRect(rect.getX(), rect.getY(), (Double)value, rect.getHeight()); break; case 3: rect.setRect(rect.getX(), rect.getY(), rect.getWidth(), (Double)value); break; default: throw new IllegalArgumentException("index out of range, expected 0..3, got "+index); } } @Override public boolean isInstance(Object obj) { return obj instanceof Rectangle2D; } @Override public void setDouble(Object r, int index, double x) throws BindingException { Rectangle2D.Double rect = (Rectangle2D.Double) r; switch (index) { case 0: rect.x = x; break; case 1: rect.y = x; break; case 2: rect.width = x; break; case 3: rect.height = x; break; default: throw new IllegalArgumentException("index out of range, expected 0..3, got "+index); } } @Override public double getDouble(Object r, int index) throws BindingException { Rectangle2D.Double rect = (Rectangle2D.Double) r; switch (index) { case 0: return rect.x; case 1: return rect.y; case 2: return rect.width; case 3: return rect.height; default: throw new IllegalArgumentException("index out of range, expected 0..3, got "+index); } } } public static void main(String[] args) throws IOException, BindingException { Datatype dataType = Datatypes.getDatatypeUnchecked(Rectangle2D.Double.class); System.out.println(dataType); Binding reflectionBinding = Bindings.getBindingUnchecked(Rectangle2D.Double.class); Binding handWrittenBinding = new Rectangle2DBinding(); System.out.println("Lets measure performance... (4,000,000 reads and 1,000,000 writes*4)"); Rectangle2D rect = new Rectangle2D.Double(5, 5, 100, 200); for ( int i=0; i<10; i++ ) { long time1 = testBinding(reflectionBinding, rect); long time2 = testBinding(handWrittenBinding, rect); time1 = testBinding(reflectionBinding, rect); time2 = testBinding(handWrittenBinding, rect); System.out.println("Time of reflection based binding: "+time1+" ms"); System.out.println("Time of Hand-Written binding: "+time2+" ms"); } } static long testBinding(Binding b, Rectangle2D rect) throws BindingException { RecordBinding record = (RecordBinding) b; Runtime.getRuntime().gc(); long timeAtStart = System.currentTimeMillis(); for (int i=0; i<10000000; i++) { record.getComponent(rect, 0); record.getComponent(rect, 1); record.getComponent(rect, 2); record.getComponent(rect, 3); record.setComponents(rect, 5.0, 5.0, 100.0, 200.0); } return System.currentTimeMillis() - timeAtStart; } }