/******************************************************************************* * Copyright (c) 2007 VTT Technical Research Centre of Finland and others. * 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.simulation.data; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Random; import org.simantics.databoard.Datatypes; import org.simantics.databoard.accessor.error.AccessorException; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.NumberBinding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.Bean; /** * Pseudo solver has three variables: Sine, Ramp and Random * * Values are sampled in real time until the solver is disposed. * * @author Toni Kalajainen */ public class PseudoSolver extends AbstractDatasource { public static String SINE = "Sine"; public static String RAMP = "Ramp"; public static String RANDOM = "Random"; public static List KEYS; Thread thread; long startTime; double time; Random random; int cycle = 0; public PseudoSolver() { super(); random = new Random(); } @Override public Collection getVariables() { return KEYS; } public void start() { thread = new Thread() { @Override public void run() { startTime = System.nanoTime(); notifyStep(); while (Thread.currentThread() == thread) { writeLock.lock(); try { if (Thread.currentThread() != thread) return; for (int i=0; i<10; i++) { cycle++; time = cycle * 0.01; notifyStep(); } } finally { writeLock.unlock(); } try {Thread.sleep(15); } catch (InterruptedException e) {} } } }; thread.start(); } public void stop() { writeLock.lock(); try { thread = null; } finally { writeLock.unlock(); } } @Override public Datatype getType(String key) { //if (key.equals("Ramp")) return Datatypes.BOOLEAN; return Datatypes.DOUBLE; } @Override public Object getTime(NumberBinding binding) { try { return binding.create(time); } catch (BindingException e) { throw new RuntimeException(e); } } @Override public VariableHandle openHandle(Bean item, String key, Binding valueBinding) { getValue(key, valueBinding); return new MyVariableHandle(key, valueBinding); } public Object getValue(String key, Binding binding) { if (binding instanceof NumberBinding == false) throw new IllegalArgumentException("binding must be NumberBinding"); NumberBinding nb = (NumberBinding) binding; try { if (key.equals(SINE)) { double value = Math.sin(time); return nb.create(value); } else if (key.equals(RAMP)) { boolean up = time - Math.floor(time) >= 0.5; double value = up ? 1.0 : 0.0; return value; } else if (key.equals(RANDOM)) { return random.nextDouble()*10; } } catch (BindingException e) { throw new RuntimeException(e); } throw new RuntimeException("Unknown variable "+key); } static { List keys = new ArrayList(); keys.add(SINE); keys.add(RAMP); keys.add(RANDOM); KEYS = Collections.unmodifiableList( keys ); } class MyVariableHandle implements VariableHandle { String key; Binding b; public MyVariableHandle(String key, Binding b) { this.b = b; this.key = key; } @Override public String key() { return key; } @Override public Binding binding() { return b; } @Override public Object getValue() { return PseudoSolver.this.getValue(key, b); } @Override public Object getValue(Datasource datasource) throws AccessorException { return PseudoSolver.this.getValue(key, b); } @Override public void dispose() { } } }