package com.laytonsmith.core.functions;
import com.laytonsmith.abstraction.StaticLayer;
import com.laytonsmith.annotations.api;
import com.laytonsmith.core.CHVersion;
import com.laytonsmith.core.Static;
import com.laytonsmith.core.constructs.CBoolean;
import com.laytonsmith.core.constructs.CClosure;
import com.laytonsmith.core.constructs.CVoid;
import com.laytonsmith.core.constructs.Construct;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.environments.Environment;
import com.laytonsmith.core.environments.GlobalEnv;
import com.laytonsmith.core.exceptions.CRE.CRECastException;
import com.laytonsmith.core.exceptions.CRE.CREThrowable;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import com.laytonsmith.core.exceptions.ProgramFlowManipulationException;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
*/
public class ExecutionQueue {
public static String docs(){
return "An execution queue is a queue of closures, which are"
+ " queued up to be run in sequence by the engine."
+ " Unlike set_timeout and set_interval, there is no"
+ " time component, it's simply a queue of operations"
+ " to execute sequentially. See the"
+ " [[CommandHelper/Execution_Queue|article on the learning trail]]"
+ " for more information.";
}
@api(environments={GlobalEnv.class})
public static class queue_push extends AbstractFunction{
@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CRECastException.class};
}
@Override
public boolean isRestricted() {
return true;
}
@Override
public Boolean runAsync() {
return null;
}
@Override
public Construct exec(Target t, final Environment environment, Construct... args) throws ConfigRuntimeException {
final CClosure c;
String queue = null;
if(!(args[0] instanceof CClosure)){
throw new CRECastException("Parameter 1 to " + getName() + " must be a closure.", t);
}
c = ((CClosure)args[0]);
if(args.length == 2){
queue = args[1].nval();
}
environment.getEnv(GlobalEnv.class).GetExecutionQueue().push(environment.getEnv(GlobalEnv.class).GetDaemonManager(), queue, new Runnable() {
@Override
public void run() {
try {
StaticLayer.GetConvertor().runOnMainThreadAndWait(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
c.execute();
} catch(ConfigRuntimeException ex){
ConfigRuntimeException.HandleUncaughtException(ex, environment);
} catch(ProgramFlowManipulationException ex){
// Ignored
}
return null;
}
});
} catch (Exception ex) {
Logger.getLogger(ExecutionQueue.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
return CVoid.VOID;
}
@Override
public String getName() {
return "queue_push";
}
@Override
public Integer[] numArgs() {
return new Integer[]{1, 2};
}
@Override
public String docs() {
return "void {closure, [queue]} Queues a task up at the end of the specified queue.";
}
@Override
public CHVersion since() {
return CHVersion.V3_3_1;
}
}
@api(environments={GlobalEnv.class})
public static class queue_push_front extends AbstractFunction{
@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CRECastException.class};
}
@Override
public boolean isRestricted() {
return true;
}
@Override
public Boolean runAsync() {
return null;
}
@Override
public Construct exec(Target t, final Environment environment, Construct... args) throws ConfigRuntimeException {
final CClosure c;
String queue = null;
if(!(args[0] instanceof CClosure)){
throw new CRECastException("Parameter 1 to " + getName() + " must be a closure.", t);
}
c = ((CClosure)args[0]);
if(args.length == 2){
queue = args[1].nval();
}
environment.getEnv(GlobalEnv.class).GetExecutionQueue().pushFront(environment.getEnv(GlobalEnv.class).GetDaemonManager(), queue, new Runnable() {
@Override
public void run() {
try {
StaticLayer.GetConvertor().runOnMainThreadAndWait(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
c.execute();
} catch(ConfigRuntimeException ex){
ConfigRuntimeException.HandleUncaughtException(ex, environment);
} catch(ProgramFlowManipulationException ex){
// Ignored
}
return null;
}
});
} catch (Exception ex) {
Logger.getLogger(ExecutionQueue.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
return CVoid.VOID;
}
@Override
public String getName() {
return "queue_push_front";
}
@Override
public Integer[] numArgs() {
return new Integer[]{1, 2};
}
@Override
public String docs() {
return "void {closure, [queue]} Queues a task at the front of the queue.";
}
@Override
public CHVersion since() {
return CHVersion.V3_3_1;
}
}
@api(environments={GlobalEnv.class})
public static class queue_remove extends AbstractFunction{
@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{};
}
@Override
public boolean isRestricted() {
return true;
}
@Override
public Boolean runAsync() {
return null;
}
@Override
public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
String queue = null;
if(args.length == 1){
queue = args[0].nval();
}
environment.getEnv(GlobalEnv.class).GetExecutionQueue().remove(queue);
return CVoid.VOID;
}
@Override
public String getName() {
return "queue_remove";
}
@Override
public Integer[] numArgs() {
return new Integer[]{0, 1};
}
@Override
public String docs() {
return "void {[queue]} Removes the last task at the end of the queue from the queue.";
}
@Override
public CHVersion since() {
return CHVersion.V3_3_1;
}
}
@api(environments={GlobalEnv.class})
public static class queue_remove_front extends AbstractFunction{
@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{};
}
@Override
public boolean isRestricted() {
return true;
}
@Override
public Boolean runAsync() {
return null;
}
@Override
public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
String queue = null;
if(args.length == 1){
queue = args[0].nval();
}
environment.getEnv(GlobalEnv.class).GetExecutionQueue().removeFront(queue);
return CVoid.VOID;
}
@Override
public String getName() {
return "queue_remove_front";
}
@Override
public Integer[] numArgs() {
return new Integer[]{0, 1};
}
@Override
public String docs() {
return "void {[queue]} Removes a task from the front of the queue. That is, the next task"
+ " that would have been run is removed.";
}
@Override
public CHVersion since() {
return CHVersion.V3_3_1;
}
}
@api(environments={GlobalEnv.class})
public static class queue_clear extends AbstractFunction{
@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{};
}
@Override
public boolean isRestricted() {
return true;
}
@Override
public Boolean runAsync() {
return null;
}
@Override
public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
String queue = null;
if(args.length == 1){
queue = args[0].nval();
}
environment.getEnv(GlobalEnv.class).GetExecutionQueue().clear(queue);
return CVoid.VOID;
}
@Override
public String getName() {
return "queue_clear";
}
@Override
public Integer[] numArgs() {
return new Integer[]{0, 1};
}
@Override
public String docs() {
return "void {[queue]} Clears out all tasks that are on the queue. If no tasks were"
+ " on the queue, nothing happens.";
}
@Override
public CHVersion since() {
return CHVersion.V3_3_1;
}
}
@api(environments={GlobalEnv.class})
public static class queue_running extends AbstractFunction{
@Override
public Class<? extends CREThrowable>[] thrown() {
return null;
}
@Override
public boolean isRestricted() {
return true;
}
@Override
public Boolean runAsync() {
return null;
}
@Override
public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
String queue = null;
if(args.length == 1){
queue = args[0].nval();
}
return CBoolean.get(environment.getEnv(GlobalEnv.class).GetExecutionQueue().isRunning(queue));
}
@Override
public String getName() {
return "queue_running";
}
@Override
public Integer[] numArgs() {
return new Integer[]{0, 1};
}
@Override
public String docs() {
return "boolean {[queue]} Returns true if the specified queue still has tasks running on it.";
}
@Override
public CHVersion since() {
return CHVersion.V3_3_1;
}
}
@api(environments={GlobalEnv.class})
public static class queue_delay extends AbstractFunction{
@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CRECastException.class};
}
@Override
public boolean isRestricted() {
return true;
}
@Override
public Boolean runAsync() {
return null;
}
@Override
public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
String queue = null;
if(args.length == 2){
queue = args[1].nval();
}
final long delay = Static.getInt(args[0], t);
environment.getEnv(GlobalEnv.class).GetExecutionQueue().push(environment.getEnv(GlobalEnv.class).GetDaemonManager(), queue, new Runnable() {
@Override
public void run() {
try {
Thread.sleep(delay);
} catch (InterruptedException ex) {
//
}
}
});
return CVoid.VOID;
}
@Override
public String getName() {
return "queue_delay";
}
@Override
public Integer[] numArgs() {
return new Integer[]{1, 2};
}
@Override
public String docs() {
return "void {x, [queue]} Queues up a non-disruptive sleep at the end of the queue. This task"
+ " will stall the execution thread for x milliseconds.";
}
@Override
public CHVersion since() {
return CHVersion.V3_3_1;
}
}
@api(environments={GlobalEnv.class})
public static class queue_delay_front extends AbstractFunction{
@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CRECastException.class};
}
@Override
public boolean isRestricted() {
return true;
}
@Override
public Boolean runAsync() {
return null;
}
@Override
public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
String queue = null;
if(args.length == 2){
queue = args[1].nval();
}
final long delay = Static.getInt(args[0], t);
environment.getEnv(GlobalEnv.class).GetExecutionQueue().pushFront(environment.getEnv(GlobalEnv.class).GetDaemonManager(), queue, new Runnable() {
@Override
public void run() {
try {
Thread.sleep(delay);
} catch (InterruptedException ex) {
//
}
}
});
return CVoid.VOID;
}
@Override
public String getName() {
return "queue_delay_front";
}
@Override
public Integer[] numArgs() {
return new Integer[]{1, 2};
}
@Override
public String docs() {
return "void {x, [queue]} Works like queue_delay, but puts the delay at the front of the queue.";
}
@Override
public CHVersion since() {
return CHVersion.V3_3_1;
}
}
}