/*
* ShellInputAnimator.java
*
* Copyright (C) 2009-12 by RStudio, Inc.
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.studio.client.workbench.views.console.shell;
import java.util.ArrayList;
import org.rstudio.studio.client.workbench.views.console.shell.editor.InputEditorDisplay;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.user.client.Command;
public class ShellInputAnimator
{
public ShellInputAnimator(InputEditorDisplay display)
{
display_ = display;
}
public void enque(String code, final Command onFinished)
{
// wrap onFinished with a check of the queue for additional commands
Command onAnimatedInputFinished = new Command() {
@Override
public void execute()
{
// perform stock finished action
onFinished.execute();
// remove from queue
pendingAnimatedInput_.remove(0);
// execute any pending inputs
executePendingAnimatedInput();
}
};
// create the input and add it to the queue
InputAnimator inputAnimator = new InputAnimator(
code,
onAnimatedInputFinished);
pendingAnimatedInput_.add(inputAnimator);
// if we are the only one in the queue then we need to manually
// force execution (otherwise we'll just get execute when the
// currently executing command completes)
if (pendingAnimatedInput_.size() == 1)
executePendingAnimatedInput();
}
private void executePendingAnimatedInput()
{
if (pendingAnimatedInput_.size() > 0)
{
// get the input animaator
InputAnimator inputAnimator = pendingAnimatedInput_.get(0);
// calculate the period (make sure the command takes no longer
// than 1600ms to input)
final int kMaxMs = 1600;
String code = inputAnimator.getCode();
int period = Math.min( kMaxMs / code.length(), 75);
// schedule it
Scheduler.get().scheduleFixedPeriod(inputAnimator, period);
}
}
private class InputAnimator implements RepeatingCommand
{
public InputAnimator(String code, Command onFinished)
{
code_ = code;
onFinished_ = onFinished;
}
public String getCode()
{
return code_;
}
@Override
public boolean execute()
{
// termination condition
if ((nextChar_ + 1) > code_.length())
{
onFinished_.execute();
return false;
}
// clear before first char
if (nextChar_ == 0)
display_.clear();
display_.insertCode(code_.substring(nextChar_, nextChar_+1));
nextChar_++;
return true;
}
private int nextChar_ = 0;
private final String code_;
private final Command onFinished_;
}
private InputEditorDisplay display_;
private ArrayList<InputAnimator> pendingAnimatedInput_ =
new ArrayList<InputAnimator>();
}