package com.laytonsmith.core.taskmanager; import com.laytonsmith.PureUtilities.Common.ReflectionUtils; import com.laytonsmith.annotations.taskhandler; import com.laytonsmith.core.constructs.Target; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * A TaskHandler is an object that actually manages the various task * types. It knows several things, including how to get display information * about a particular task, as well as how to manipulate the task (and if the * task can be manipulated at all). */ public abstract class TaskHandler { private final Set<TaskStateChangeListener> stateChangeListeners = new HashSet<>(); private final taskhandler annotation; private TaskState state = TaskState.REGISTERED; private TaskType type; private int id; private Target target; protected TaskHandler(TaskType type, int id, Target target){ this.annotation = this.getClass().getAnnotation(taskhandler.class); if(this.annotation == null){ throw new RuntimeException("All instances of TaskHandler must be tagged with the @taskhandler"); } this.type = type; this.id = id; this.target = target; } /** * Adds a state change listener to the task manager. When a task's state changes, it * will be sent to all listeners. * @param listener */ public void addStateChangeListener(TaskStateChangeListener listener){ stateChangeListeners.add(listener); } /** * Removes a state change listener. * @param listener */ public void removeStateChangeListener(TaskStateChangeListener listener){ stateChangeListeners.remove(listener); } public synchronized void changeState(TaskState changeTo){ TaskState old = this.getState(); this.state = changeTo; for(TaskStateChangeListener listener : stateChangeListeners){ listener.taskStateChanged(old, this); } } /** * Returns the current state of the task. * @return */ public final TaskState getState(){ return this.state; } /** * Returns a list of properties * @return */ public final String[] getProperties(){ return annotation.properties(); } /** * Returns a map of properties and their data. * @return */ public final Map<String, Object> getPropertyData(){ Map<String, Object> data = new HashMap<>(); for(String prop : getProperties()){ data.put(prop, ReflectionUtils.get(this.getClass(), this, "get" + prop)); } return data; } /** * Returns the id of the task. This is not necessarily unique across all tasks, but * should be unique across each task type. Another id, based on the task * @return */ public final int getID(){ return id; } /** * Gets the TaskType of this task. * @return */ public final TaskType getType(){ return type; } /** * Returns the code target for where this task was defined at. * @return */ public final Target getDefinedAt(){ return target; } /** * Attempts to kill the task. */ public abstract void kill(); }