/******************************************************************************* * Copyright (c) 2009-2013 CWI * 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 *******************************************************************************/ package org.rascalmpl.eclipse.library.vis.figure.interaction; import static org.rascalmpl.eclipse.library.vis.Timer.TimerAction_noChange; import static org.rascalmpl.eclipse.library.vis.Timer.TimerAction_restart; import static org.rascalmpl.eclipse.library.vis.Timer.TimerAction_restart_delay; import static org.rascalmpl.eclipse.library.vis.Timer.TimerAction_stop; import static org.rascalmpl.eclipse.library.vis.Timer.TimerInfo; import static org.rascalmpl.eclipse.library.vis.Timer.TimerInfo_running; import static org.rascalmpl.eclipse.library.vis.Timer.TimerInfo_stopped; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.rascalmpl.interpreter.result.Result; import org.rascalmpl.eclipse.library.vis.figure.Figure; import org.rascalmpl.eclipse.library.vis.figure.combine.LayoutProxy; import org.rascalmpl.eclipse.library.vis.properties.PropertyManager; import org.rascalmpl.eclipse.library.vis.swt.ICallbackEnv; import org.rascalmpl.eclipse.library.vis.swt.IFigureConstructionEnv; import org.rascalmpl.eclipse.library.vis.util.NameResolver; import io.usethesource.vallang.IConstructor; import io.usethesource.vallang.IValue; import io.usethesource.vallang.IValueFactory; import io.usethesource.vallang.type.Type; import org.rascalmpl.values.ValueFactoryFactory; public class Timer extends LayoutProxy { private static final IValueFactory vf = ValueFactoryFactory.getValueFactory(); @SuppressWarnings("unused") private static final boolean debug = true; ExecuteTimer t; ICallbackEnv cbenv; IValue timerInit; IValue callback; Control c; long elapsedAtHide; boolean hidden; IConstructor timerAction; boolean firstDraw = true; public Timer(IFigureConstructionEnv env, IValue timerInit, IValue callback, Figure inner, PropertyManager properties){ super(inner,properties); hidden = true; elapsedAtHide = 0; this.timerInit = timerInit; this.callback = callback; this.cbenv = env.getCallBackEnv(); c = env.getSWTParent(); t = null; } public void hideElement(IFigureConstructionEnv env) { if(!hidden && t != null){ t.cancel = true; elapsedAtHide = System.currentTimeMillis() - t.beginTime; hidden = true; } } public void initElem(IFigureConstructionEnv env, MouseOver mparent, boolean swtSeen, boolean visible, NameResolver resolver){ if(!visible) { return; } IValue timerInfo = getTimerInfo(); //if(debug)System.out.printf("timerInit %s\n", timerInfo); Result<IValue> result = cbenv.executeRascalCallBackSingleArgument(timerInit, TimerInfo, timerInfo); if (result != null && result.getValue() != null) { timerAction = (IConstructor) result.getValue(); executeTimerAction(timerAction); hidden = false; } } private void executeTimerAction(IConstructor timerAction){ Type type = timerAction.getConstructorType(); if(type == TimerAction_noChange){ if(hidden){ if(t !=null){ int newDelay = (int)(t.delay - elapsedAtHide); t = new ExecuteTimer(newDelay); } } else { return; } } else if(type == TimerAction_stop){ if(t !=null){ t.cancel = true; t.stopped = true; } } else if(type == TimerAction_restart){ if(t != null){ t.cancel = true; } t = new ExecuteTimer(TimerAction_restart_delay(timerAction)); //System.out.printf("Restarting time %d %s\n", TimerAction_restart_delay(timerAction),t); } else { System.err.printf("Unknown timerAction type %s %s!\n ", type, timerAction); } } private IValue getTimerInfo(){ if(t == null){ return vf.constructor(TimerInfo_stopped, vf.integer(0)); } else { if(t.stopped){ return vf.constructor(TimerInfo_stopped, vf.integer(System.currentTimeMillis() - t.stopTime)); } else { return vf.constructor(TimerInfo_running, vf.integer(t.delay - (System.currentTimeMillis() - t.beginTime))); } } } class ExecuteTimer implements Runnable{ boolean cancel; long beginTime; long stopTime; boolean stopped; int delay; ExecuteTimer(int delay){ cancel = false; stopped = false; beginTime = System.currentTimeMillis(); if(delay <= 0){ delay = 1; } this.delay = delay; //if(debug)System.out.printf("Executing timer delay %s\n",delay); Display.getCurrent().timerExec(delay, this); } public void run() { //if(debug)System.out.printf("Timer callbakc!"); if(cancel || c.isDisposed()) { //System.out.printf("Cancelled! %d %s \n",delay, this); return; } //System.out.printf("Executing! %d %s \n",delay, this); cbenv.executeRascalCallBackWithoutArguments(callback); stopped =true; stopTime = System.currentTimeMillis(); cbenv.signalRecompute(); } } }