init, thx MrExtremez

This commit is contained in:
Nicola Paolucci
2019-06-18 15:04:35 -04:00
commit ea51313125
2488 changed files with 150207 additions and 0 deletions
@@ -0,0 +1,22 @@
package redone.event;
/**
* What the event must implement
*
* @author Stuart <RogueX>
*/
public abstract class CycleEvent {
/**
* Code which should be ran when the event is executed
*
* @param container
*/
public abstract void execute(CycleEventContainer container);
/**
* Code which should be ran when the event stops
*/
public abstract void stop();
}
@@ -0,0 +1,137 @@
package redone.event;
/**
* The wrapper for our event
*
* @author Stuart <RogueX>
* @author Null++
*/
public class CycleEventContainer {
/**
* Event owner
*/
private final Object owner;
/**
* Is the event running or not
*/
private boolean isRunning;
/**
* The amount of cycles per event execution
*/
private int tick;
/**
* The actual event
*/
private final CycleEvent event;
/**
* The current amount of cycles passed
*/
private int cyclesPassed;
/**
* The event ID
*/
private final int eventID;
/**
* Sets the event containers details
*
* @param owner
* , the owner of the event
* @param event
* , the actual event to run
* @param tick
* , the cycles between execution of the event
*/
public CycleEventContainer(int id, Object owner, CycleEvent event, int tick) {
eventID = id;
this.owner = owner;
this.event = event;
isRunning = true;
cyclesPassed = 0;
this.tick = tick;
}
/**
* Execute the contents of the event
*/
public void execute() {
event.execute(this);
}
/**
* Stop the event from running
*/
public void stop() {
isRunning = false;
event.stop();
}
/**
* Does the event need to be ran?
*
* @return true yes false no
*/
public boolean needsExecution() {
if (!isRunning()) {
return false;
}
if (++cyclesPassed >= tick) {
cyclesPassed = 0;
return true;
}
return false;
}
/**
* Returns the owner of the event
*
* @return
*/
public Object getOwner() {
return owner;
}
/**
* Is the event running?
*
* @return true yes false no
*/
public boolean isRunning() {
return isRunning;
}
/**
* Returns the event id
*
* @return id
*/
public int getID() {
return eventID;
}
/**
* Returns the current cycle/tick.
*
* @return
*/
public int getTick() {
return tick;
}
/**
* Set the amount of cycles between the execution
*
* @param tick
*/
public void setTick(int tick) {
this.tick = tick;
}
}
@@ -0,0 +1,138 @@
package redone.event;
import java.util.ArrayList;
import java.util.List;
/**
* Handles all of our cycle based events
*
* @author Stuart <RogueX>
* @author Null++
*/
public class CycleEventHandler {
/**
* The instance of this class
*/
private static CycleEventHandler instance;
/**
* Returns the instance of this class
*
* @return
*/
public static CycleEventHandler getSingleton() {
if (instance == null) {
instance = new CycleEventHandler();
}
return instance;
}
/**
* Holds all of our events currently being ran
*/
private final List<CycleEventContainer> events;
/**
* Creates a new instance of this class
*/
public CycleEventHandler() {
events = new ArrayList<CycleEventContainer>();
}
/**
* Add an event to the list
*
* @param id
* @param owner
* @param event
* @param cycles
*/
public void addEvent(int id, Object owner, CycleEvent event, int cycles) {
events.add(new CycleEventContainer(id, owner, event, cycles));
}
/**
* Add an event to the list
*
* @param owner
* @param event
* @param cycles
*/
public void addEvent(Object owner, CycleEvent event, int cycles) {
events.add(new CycleEventContainer(-1, owner, event, cycles));
}
/**
* Execute and remove events
*/
public void process() {
List<CycleEventContainer> eventsCopy = new ArrayList<CycleEventContainer>(
events);
List<CycleEventContainer> remove = new ArrayList<CycleEventContainer>();
for (CycleEventContainer c : eventsCopy) {
if (c != null) {
if (c.needsExecution() && c.isRunning()) {
c.execute();
if (!c.isRunning()) {
remove.add(c);
}
}
}
}
for (CycleEventContainer c : remove) {
events.remove(c);
}
}
/**
* Returns the amount of events currently running
*
* @return amount
*/
public int getEventsCount() {
return events.size();
}
/**
* Stops all events for a specific owner and id
*
* @param owner
*/
public void stopEvents(Object owner) {
for (CycleEventContainer c : events) {
if (c.getOwner() == owner) {
c.stop();
}
}
}
/**
* Stops all events for a specific owner and id
*
* @param owner
* @param id
*/
public void stopEvents(Object owner, int id) {
for (CycleEventContainer c : events) {
if (c.getOwner() == owner && id == c.getID()) {
c.stop();
}
}
}
/**
* Stops all events for a specific owner and id
*
* @param id
*/
public void stopEvents(int id) {
for (CycleEventContainer c : events) {
if (id == c.getID()) {
c.stop();
}
}
}
}
@@ -0,0 +1,180 @@
package redone.event;
/**
* Represents a periodic task that can be scheduled with a {@link TaskScheduler}
* .
*
* @author Graham
*/
public abstract class Task {
/**
* The number of cycles between consecutive executions of this task.
*/
private final int delay;
/**
* A flag which indicates if this task should be executed once immediately.
*/
private final boolean immediate;
/**
* The current 'count down' value. When this reaches zero the task will be
* executed.
*/
private int countdown;
/**
* A flag which indicates if this task is still running.
*/
private boolean running = true;
/**
* Creates a new task with a delay of 1 cycle.
*/
public Task() {
this(1);
}
/**
* Creates a new task with a delay of 1 cycle and immediate flag.
*
* @param immediate
* A flag that indicates if for the first execution there should
* be no delay.
*/
public Task(boolean immediate) {
this(1, immediate);
}
/**
* Creates a new task with the specified delay.
*
* @param delay
* The number of cycles between consecutive executions of this
* task.
* @throws IllegalArgumentException
* if the {@code delay} is not positive.
*/
public Task(int delay) {
this(delay, false);
}
/**
* Creates a new task with the specified delay and immediate flag.
*
* @param delay
* The number of cycles between consecutive executions of this
* task.
* @param immediate
* A flag which indicates if for the first execution there should
* be no delay.
* @throws IllegalArgumentException
* if the {@code delay} is not positive.
*/
public Task(int delay, boolean immediate) {
checkDelay(delay);
this.delay = delay;
countdown = delay;
this.immediate = immediate;
}
/**
* Checks if this task is an immediate task.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean isImmediate() {
return immediate;
}
/**
* Checks if the task is running.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean isRunning() {
return running;
}
/**
* Checks if the task is stopped.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean isStopped() {
return !running;
}
/**
* This method should be called by the scheduling class every cycle. It
* updates the {@link #countdown} and calls the {@link #execute()} method if
* necessary.
*
* @return A flag indicating if the task is running.
*/
public boolean tick() {
if (running && --countdown == 0) {
execute();
countdown = delay;
}
return running;
}
/**
* Performs this task's action.
*/
protected abstract void execute();
/**
* Changes the delay of this task.
*
* @param delay
* The number of cycles between consecutive executions of this
* task.
* @throws IllegalArgumentException
* if the {@code delay} is not positive.
*/
public void setDelay(int delay) {
checkDelay(delay);
delay = 0;
}
/**
* Stops this task.
*
* @throws IllegalStateException
* if the task has already been stopped.
*/
public void stop() {
checkStopped();
running = false;
}
/**
* Checks if the delay is negative and throws an exception if so.
*
* @param delay
* The delay.
* @throws IllegalArgumentException
* if the delay is not positive.
*/
private void checkDelay(int delay) {
if (delay <= 0) {
throw new IllegalArgumentException("Delay must be positive.");
}
}
/**
* Checks if this task has been stopped and throws an exception if so.
*
* @throws IllegalStateException
* if the task has been stopped.
*/
private void checkStopped() {
if (!running) {
throw new IllegalStateException();
}
}
}
@@ -0,0 +1,114 @@
package redone.event;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A class which schedules the execution of {@link Task}s.
*
* @author Graham
*/
public final class TaskScheduler implements Runnable {
/**
* A logger used to report error messages.
*/
private static final Logger logger = Logger.getLogger(TaskScheduler.class
.getName());
/**
* The time period, in milliseconds, of a single cycle.
*/
private static final int TIME_PERIOD = 600;
/**
* The {@link ScheduledExecutorService} which schedules calls to the
* {@link #run()} method.
*/
private final ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
/**
* A list of active tasks.
*/
private final List<Task> tasks = new ArrayList<Task>();
/**
* A queue of tasks that still need to be added.
*/
private final Queue<Task> newTasks = new ArrayDeque<Task>();
/**
* Creates and starts the task scheduler.
*/
public TaskScheduler() {
service.scheduleAtFixedRate(this, 0, TIME_PERIOD, TimeUnit.MILLISECONDS);
}
/**
* Stops the task scheduler.
*/
public void terminate() {
service.shutdown();
}
/**
* Schedules the specified task. If this scheduler has been stopped with the
* {@link #terminate()} method the task will not be executed or
* garbage-collected.
*
* @param task
* The task to schedule.
*/
public void schedule(final Task task) {
if (task.isImmediate()) {
service.execute(new Runnable() {
@Override
public void run() {
task.execute();
}
});
}
synchronized (newTasks) {
newTasks.add(task);
}
}
/**
* This method is automatically called every cycle by the
* {@link ScheduledExecutorService} and executes, adds and removes
* {@link Task}s. It should not be called directly as this will lead to
* concurrency issues and inaccurate time-keeping.
*/
@Override
public void run() {
synchronized (newTasks) {
Task task;
while ((task = newTasks.poll()) != null) {
tasks.add(task);
}
}
for (Iterator<Task> it = tasks.iterator(); it.hasNext();) {
Task task = it.next();
try {
if (!task.tick()) {
it.remove();
}
} catch (Throwable t) {
logger.log(Level.SEVERE, "Exception during task execution.", t);
}
}
}
}