Thread: Cycle Based Task Handler

Page 1 of 3 123 LastLast
Results 1 to 10 of 25
  1. #1 Cycle Based Task Handler 
    Java Programmer
    _Jon's Avatar
    Join Date
    Jan 2015
    Age
    30
    Posts
    206
    Thanks given
    36
    Thanks received
    63
    Rep Power
    47


    This is my last revision of this Cycle Based Task Manager. Thanks again to Lare96 and Ryley.



    Task.java
    Code:
    package com.evolution.engine.task;
    
    import java.util.Optional;
    
    /**
     * <p>
     * A dynamic mutable task ; which processes the context the abstract execute
     * method. Each task have a mutable delay that is initially set upon contruction
     * of the task, When the <code>currentTick</code> is equal to the
     * <code>delay</code> then the <code>execute</code> method will be called upon ; 
     * this will continue to occur intill the task is canceled.
     * </p>
     * 
     * <p>
     * Tasks contain a overridable method <code>onCancelation</code> which can be used 
     * to context an event upon cancelation of a task.
     * </p>
     * 
     * <p>
     * Tasks also contain an optional attachment to link the task with a specific object.
     * If there is not attachment by default the optional should return <code>Optional.empty()</code>.
     * </p>
     * 
     * Author: Jon Hultin link: "http://www.rune-server.org/members/laura+bodewig/"
     * Type: Task 
     * Date: Feb 1, 2015 
     * Time: 1:12:13 AM
     *
     */
    public abstract class Task {
    	
    	/**
    	 * The name of the task.
    	 */
    	protected final String taskName;
    	
    	/**
    	 * The delay of the task.
    	 */
    	protected int delay;
    	
    	/**
    	 * The current tick of the task.
    	 */
    	protected int currentTick;
    	
    	/**
    	 * The cancelation flag.
    	 */
    	protected boolean canceled;
    	
    	/**
    	 * Constructs a new {@link #Task(String, int, boolean)} with a set task name 
    	 * and delay. You can also flag the task to execute immediatly.
    	 * 
    	 * @param taskName the name of this task.
    	 * @param delay the delay of this task.
    	 * @param execute will this task execute immediatly.
    	 */
    	public Task(String taskName, int delay, boolean execute) {
    		
    		this.taskName = taskName;
    		
    		this.delay = delay;
    		
    		this.currentTick = execute ? delay : 0;
    		
    		this.canceled = false;
    		
    	}
    	
    	/**
    	 * Processes the task to be executed.
    	 */
    	public final void process() {
    		
    		if (!canceled) {
    			
    			if (currentTick == delay) {
    				
    				this.execute();
    				
    				this.currentTick = 0;
    				
    			}
    			
    			this.currentTick++;
    			
    		}
    		
    	}
    	
    	/**
    	 * Gets the delay of the task.
    	 * 
    	 * @return the value of the delay.
    	 */
    	public final int getDelay() {
    	
    		return delay;
    	
    	}
    
    	/**
    	 * Sets a new delay for the task.
    	 * 
    	 * @param delay the new delay value.
    	 */
    	public final void setDelay(int delay) {
    	
    		this.delay = delay;
    	
    	}
    
    	/**
    	 * Gets the name of the task.
    	 * 
    	 * @return the name of the task.
    	 */
    	public final String getTaskName() {
    	
    		return taskName;
    	
    	}
    
    	/**
    	 * Checks if the task is canceled.
    	 * 
    	 * @return the current state of cancel.
    	 */
    	public final boolean isCanceled() {
    	
    		return canceled;
    	
    	}
    	
    	/**
    	 * Cancels the task and calls the <code>onCancelation</code> method.
    	 */
    	public final void cancel() {
    		
    		this.canceled = true;
    		
    		this.onCancelation();
    		
    	}
    
    	/**
    	 * The optional task attachment.
    	 * 
    	 * @return the attachment object.
    	 */
    	public abstract Optional<Object> getAttachment();
    	
    	/**
    	 * The tasks execution context method.
    	 */
    	public abstract void execute();
    	
    	/**
    	 * An overridable skeleton method for an event to occur upon cancelation.
    	 */
    	public void onCancelation() { };
    
    }
    TaskManager.java
    Code:
    package com.evolution.engine.task;
    
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.Objects;
    import java.util.Optional;
    import java.util.Queue;
    import java.util.function.Predicate;
    
    /**
     * <p>
     * A manager which handles the scheduling, cancelation, removal, validation, and 
     * execution of {@link task#Task}(s).
     * </p>
     * 
     * Author: Jon Hultin link: "http://www.rune-server.org/members/laura+bodewig/"
     * Type: TaskManager
     * Date: Feb 1, 2015 
     * Time: 1:14:27 AM
     *
     */
    public final class TaskManager {
    	
    	/**
    	 * A queue of {@link task#Task}(s) awaiting validation.
    	 */
    	private static final Queue<Task> validation = new LinkedList<>();
    	
    	/**
    	 * A queue of {@link task#Task}(s) awaiting execution.
    	 */
    	private static final Queue<Task> validated = new LinkedList<>();
    	
    	/**
    	 * Constructs a new {@link #TaskManager()} which will throw and exception because 
    	 * this class doesn't need to be instanced.
    	 */
    	public TaskManager() {
    		
    		throw new UnsupportedOperationException("This class can't be instanced.");
    		
    	}
    	
    	/**
    	 * Processes the validation and execution of the {@link task#Task}(s).
    	 */
    	public static void process() {
    		
    		validation.removeIf(Objects::isNull);
    		
    		validated.removeIf(Objects::isNull);
    		
    		validation.removeIf(Task::isCanceled);
    		
    		validated.removeIf(Task::isCanceled);
    		
    		while (!validation.isEmpty()) {
    			
    			validated.add(validation.poll());
    			
    		}
    		
    		validated.forEach(Task::process);
    		
    	}
    	
    	/**
    	 * Schedules a new {@link task#Task}.
    	 * 
    	 * @param task the task being scheduled.
    	 */
    	public static void schedule(Task task) {
    		
    		validation.offer(task);
    		
    	}
    	
    	/**
    	 * Schedules an array of {@link task#Task}(s).
    	 * 
    	 * @param tasks the tasks being scheduled.
    	 */
    	public static void schedule(Task... tasks) {
    		
    		Arrays.stream(tasks).forEach(TaskManager::schedule);
    		
    	}
    	
    	/**
    	 * Removes a specific {@link task#Task} directly from the {@link #validated} collection if it has an 
    	 * attachment present. This method is only ment to be used with task that contain an attachment
    	 * use {@link #cancel(String)} otherwise.
    	 * 
    	 * @param attachment the attachment linked to the task.
    	 * @param taskName the name of the task.
    	 */
    	public static void remove(Object attachment, String taskName) {
    		
    		Predicate<Task> attachedTo = task -> task.getAttachment().equals(Optional.of(attachment));
    		
    		Predicate<Task> isNamed = task -> task.getTaskName().equals(taskName);
    		
    		Optional<Task> task = validated.stream().filter(attachedTo).filter(isNamed).findFirst();
    		
    		task.ifPresent(validated::remove);
    		
    	}
    	
    	/**
    	 * Cancels a {@link task#Task} based on its name.
    	 * 
    	 * @param taskName the name of the task being canceled.
    	 */
    	public static void cancel(String taskName) {
    		
    		validated.forEach(task -> { 
    			
    			if (task.taskName.equals(taskName)) { 
    				
    				task.cancel();
    				
    			} 
    			
    		});
    		
    	}
    	
    	/**
    	 * Canceleds an array of {@link task#Task}(s) based on there names.
    	 * 
    	 * @param taskNames the names of the tasks being canceled.
    	 */
    	public static void cancel(String... taskNames) {
    		
    		Arrays.stream(taskNames).forEach(TaskManager::cancel);
    		
    	}
    	
    	/**
    	 * Cancels all validated {@link task#Task}(s).
    	 */
    	public static void cancelAll() {
    		
    		validated.forEach(Task::cancel);
    		
    	}
    
    }

    Reply With Quote  
     

  2. Thankful user:


  3. #2  
    Banned Cycle Based Task Handler Market Banned


    Join Date
    Jan 2011
    Age
    26
    Posts
    3,112
    Thanks given
    1,198
    Thanks received
    1,479
    Rep Power
    0
    Code:
    	public Optional<Object> getAttachment() {
    		
    		return null;
    		
    	}
    should be 'return Optional.empty();'


    Code:
    	public static final void remove(Object attachment) {
    		
    		CURRENT_TASKS.stream().filter(t -> t.getAttachment().equals(Optional.ofNullable(attachment))).forEach(t -> t.cancel());
    
    	}
    be sure you're comparing the value within the optional and not the actual optional instances!! (or it isn't going to work)


    otherwise great job bro, looking tons better
    Reply With Quote  
     

  4. #3  
    Java Programmer
    _Jon's Avatar
    Join Date
    Jan 2015
    Age
    30
    Posts
    206
    Thanks given
    36
    Thanks received
    63
    Rep Power
    47
    Quote Originally Posted by lare96 View Post
    Code:
    	public Optional<Object> getAttachment() {
    		
    		return null;
    		
    	}
    should be 'return Optional.empty();'


    Code:
    	public static final void remove(Object attachment) {
    		
    		CURRENT_TASKS.stream().filter(t -> t.getAttachment().equals(Optional.ofNullable(attachment))).forEach(t -> t.cancel());
    
    	}
    be sure you're comparing the value within the optional and not the actual optional instances!! (or it isn't going to work)


    otherwise great job bro, looking tons better
    Thanks for the help updated.
    Github - Here
    Reply With Quote  
     

  5. #4  
    Renown Programmer & Respected Member

    Ryley's Avatar
    Join Date
    Aug 2011
    Posts
    596
    Thanks given
    254
    Thanks received
    521
    Rep Power
    1332
    Code:
    	/**
    	 * A queue of {@link task#Task}(s) that are processed after submittion before 
    	 * being sent to {@link #CURRENT_TASKS}. 
    	 */
    	public static final Queue<Task> TASK_PROCESSING_QUEUE = new LinkedList<Task>();
    
    	/**
    	 * A list of all the currently running {@link task#Task}(s).
    	 */
    	public static final List<Task> CURRENT_TASKS = new LinkedList<Task>();
    These are not 'constants', just because they are marked static and final does not mean they are a constant by definition; constants are immutable in their instance and their contents.

    Example:

    Code:
    private static final Point POINT = new Point(1, 3);
    
    static {
        POINT.x = 5; // assume 'x' is public and not final, this is valid.
    }
    What appears to be a 'constant' is actually not, when you call it you expect point at 1, 3 instead you get 5, 3

    Same for your collections.

    Code:
    		TASK_PROCESSING_QUEUE.removeIf((t) -> (t == null));
    		
    		TASK_PROCESSING_QUEUE.removeIf((t) -> !(t.isRunning()));
    		
    		TASK_PROCESSING_QUEUE.forEach((t) -> (CURRENT_TASKS.add(TASK_PROCESSING_QUEUE.poll())));
    		
    		CURRENT_TASKS.removeIf((t) -> !(t.isRunning()));
    		
    		CURRENT_TASKS.forEach(t -> (t.process()));
    Loosen up on your parenthesis, this isn't a dialect of Lisp; it looks unnatural.

    Also here is a good place to use method referencing...

    i.e:

    Code:
    TASK_PROCESSING_QUEUE.removeIf((t) -> (t == null));
    
    // will become ->
    
    TASK_PROCESSING_QUEUE.removeIf(Objects::isNull);
    
    // ---
    CURRENT_TASKS.forEach(t -> (t.process()));
    
    // will become ->
    		
    CURRENT_TASKS.forEach(Task::process);
    Code:
    t.getAttachment().get() == attachment
    You should not be comparing objects like this, .equals.

    Also you should rarely be using Optional#get method anyway; use its built-in streams:

    Example:

    Code:
    Task task = ...
    task.getAttachment().isPresent(task -> {
        ...
    });
    Code:
    Preconditions.checkArgument(delay > 0, new IllegalStateException("A task delay can't be less than or equal to 0."));
    The exception is redundant, Preconditions#checkArgument has a method which accepts a String as the error message (and will throw it if an error occurs)
    I understand that this method accepts different exception types to provide more readable or helpful information for debugging an error, but here it is unnecessary.

    The default IllegalArgumentException is sufficient.


    Code:
    new LinkedList<Task>();
    Diamond operator has existed since Java 7, use it. :- )
    Reply With Quote  
     


  6. #5  
    Java Programmer
    _Jon's Avatar
    Join Date
    Jan 2015
    Age
    30
    Posts
    206
    Thanks given
    36
    Thanks received
    63
    Rep Power
    47
    Thanks for the feedback will update when I get back from work.
    Reply With Quote  
     

  7. #6  
    Renown Programmer & Respected Member

    Ryley's Avatar
    Join Date
    Aug 2011
    Posts
    596
    Thanks given
    254
    Thanks received
    521
    Rep Power
    1332
    Another note; do not mark static methods final, it serves no purpose.

    Do not mark methods final if they are within a final class
    Do mark methods final if they are at risk of being overridden and should not be.

    Code:
    processingTasks.removeIf(task -> task == null);
    		
    // *snip*
    		
    runningTasks.forEach(task -> task.process());
    This can still be shortened up:

    Code:
    processingTasks.removeIf(Objects::isNull);
    		
    runningTasks.forEach(Task::process);
    Reply With Quote  
     

  8. Thankful users:


  9. #7  
    Java Programmer
    _Jon's Avatar
    Join Date
    Jan 2015
    Age
    30
    Posts
    206
    Thanks given
    36
    Thanks received
    63
    Rep Power
    47
    Quote Originally Posted by TrollMonkey View Post
    This is crap, just use graham's version of this. Nice try doe grill.
    I shocked that a monkey doesn't know what crap look like seeing as you play with it everyday.....
    Github - Here
    Reply With Quote  
     

  10. #8  
    Renown Programmer & Respected Member

    Ryley's Avatar
    Join Date
    Aug 2011
    Posts
    596
    Thanks given
    254
    Thanks received
    521
    Rep Power
    1332
    Hi again;

    Code:
    	/**
    	 * A queue of {@link task#Task}(s) that are processed after submittion before 
    	 * being sent to {@link #runningTasks}. 
    	 */
    	public static Queue<Task> processingTasks = new LinkedList<>();
    
    	/**
    	 * A list of all the currently running {@link task#Task}(s).
    	 */
    	public static List<Task> runningTasks = new LinkedList<>();
    If you were to use the least specific type here, choose one or the other, List or Queue (LinkedList implements both)

    Also when I told you to not finalize static methods, that did not apply to fields, these collection instances are now mutable and should not be.
    Reply With Quote  
     

  11. Thankful users:


  12. #9  
    Java Programmer
    _Jon's Avatar
    Join Date
    Jan 2015
    Age
    30
    Posts
    206
    Thanks given
    36
    Thanks received
    63
    Rep Power
    47
    Quote Originally Posted by Ryley View Post
    Hi again;

    Code:
    	/**
    	 * A queue of {@link task#Task}(s) that are processed after submittion before 
    	 * being sent to {@link #runningTasks}. 
    	 */
    	public static Queue<Task> processingTasks = new LinkedList<>();
    
    	/**
    	 * A list of all the currently running {@link task#Task}(s).
    	 */
    	public static List<Task> runningTasks = new LinkedList<>();
    If you were to use the least specific type here, choose one of the other, List or Queue (LinkedList implements both)

    Also when I told you to not finalize static methods, that did not apply to fields, these collection instances are now mutable and should not be.
    Lol forgot to update this I already realized both of these I've actual rewrote this again just haven't released it though. Thanks for info.
    Github - Here
    Reply With Quote  
     

  13. #10  
    Donator


    Join Date
    Mar 2013
    Age
    24
    Posts
    1,767
    Thanks given
    335
    Thanks received
    386
    Rep Power
    318
    Quote Originally Posted by Ryley View Post
    Code:
    processingTasks.removeIf(Objects::isNull);
            
    runningTasks.forEach(Task::process);
    Hi there, what is that operator/expression called? "::"

    @OP I've implemented a similar system into my application(s), however I tend to create my own composite task executor. Its basically a task executor (with extra functionality) but contains declares a ScheduledExecutorService to execute given tasks. Therefore tasks can be executed simultaneous and are asynchronous.
    Reply With Quote  
     

Page 1 of 3 123 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Cycle-based Task Manager
    By Graham in forum Tutorials
    Replies: 68
    Last Post: 11-23-2013, 12:14 AM
  2. Modified Cycle Based Event Handler
    By Omoshu in forum Tutorials
    Replies: 50
    Last Post: 08-30-2013, 02:01 PM
  3. Cycle based events handler
    By Spooky in forum Tutorials
    Replies: 36
    Last Post: 10-13-2012, 12:58 PM
  4. Cycle-based task manager problem
    By Nighel in forum Help
    Replies: 6
    Last Post: 03-16-2012, 10:50 AM
  5. Replies: 0
    Last Post: 12-18-2011, 04:49 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •