/* * Created by Andrey Cherkashin (acherkashin) * http://acherkashin.me * * License * Copyright (c) 2015 Andrey Cherkashin * The project released under the MIT license: http://opensource.org/licenses/MIT */ package ragefist.core; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.logging.Logger; /** * * @author acherkashin */ public abstract class ProcessorTask { public static interface IProcessorTaskDelegate { public void whenTaskIsFinished(ProcessorTask task); } private static int _nextId = 0; private Processor _processor; private final int _id; private WeakReference<IProcessorTaskDelegate> _delegate; private boolean _isAsync = false; private Object _data; private boolean _result; private String _error; private boolean _isFinished = false; private Object _attachment = null; private ProcessorTask _nextTask = null; private Processor _nextTaskProcessor = null; private ProcessorTask _parentTask = null; private long _startTime; private long _finishTime; // ---------------------------------------------------------------------- // // PUBLIC // ---------------------------------------------------------------------- // public ProcessorTask() { _id = ++_nextId; if (_nextId == Integer.MAX_VALUE) { _nextId = 1; } } public long getExecutionTime() { return _finishTime - _startTime; } // ---------------------------------------------------------------------- // // NEXT TASK // A next task will be execute when this task is finished, whatever result // it is // ---------------------------------------------------------------------- // public final void setNextTask(ProcessorTask task) { _nextTask = task; _nextTaskProcessor = null; } public final void setNextTask(ProcessorTask task, Processor processor) { _nextTask = task; _nextTaskProcessor = processor; } public final ProcessorTask getNextTask() { return _nextTask; } public final Processor getNextTaskProcessor() { return _nextTaskProcessor; } // ---------------------------------------------------------------------- // // PARENT TASK // For accessing previous task's results // ---------------------------------------------------------------------- // public final void setParentTask(ProcessorTask task) { _parentTask = task; } public final ProcessorTask getParentTask() { return _parentTask; } // ---------------------------------------------------------------------- // // ATTACHMENTS // For storing and accessing custom attachment // ---------------------------------------------------------------------- // public final void setAttachment(Object object) { _attachment = object; } public final Object getAttachment() { return _attachment; } // ---------------------------------------------------------------------- // // DELEGATE // The object that will be notified when the task is finished (whatever // result it is) // ---------------------------------------------------------------------- // public final void setDelegate(IProcessorTaskDelegate delegate) { _delegate = new WeakReference<>(delegate); } public final IProcessorTaskDelegate getDelegate() { return _delegate != null ? _delegate.get() : null; } // ---------------------------------------------------------------------- // // GETTERS // ---------------------------------------------------------------------- // public final int getId() { return _id; } public final boolean getResult() { return _result; } public final Object getData() { return _data; } public final String getError() { return _error; } public final boolean isAsync() { return _isAsync; } public final boolean isFinished() { return _isFinished; } // ---------------------------------------------------------------------- // // SETTERS // ---------------------------------------------------------------------- // public final void setAsync(boolean isAsync) { _isAsync = isAsync; } // ---------------------------------------------------------------------- // // EXECUTION // ---------------------------------------------------------------------- // public final void execute(Processor processor) { _startTime = System.currentTimeMillis(); _processor = processor; boolean result = _executeImpl(_processor); if (_isAsync == false) { if (result) { this.complete(); } else { this.fail(); } } } // ---------------------------------------------------------------------- // // COMPLETION // ---------------------------------------------------------------------- // public final void finishWithResults(ProcessorTask task) { _result = task._result; _data = task._data; _error = task._error; _finish(); } public final void complete() { completeWithData(null); } public final void completeWithData(Object data) { _result = true; _data = data; _finish(); } public final void fail() { failWithErrorAndData(null, null); } public final void failWithError(String error) { failWithErrorAndData(error, null); } public final void failWithErrorAndData(String error, Object data) { _result = false; _error = error; _data = data; _finish(); } private void _finish() { if (_isFinished) { Logger.getLogger(ProcessorTask.class.getName()).warning("Attempt to finish a task twice. " + Arrays.toString(Thread.currentThread().getStackTrace())); return; } _isFinished = true; _finishTime = System.currentTimeMillis(); if (this.getDelegate() != null) { this.getDelegate().whenTaskIsFinished(this); } if (this.getNextTask() != null) { _nextTask.setParentTask(this); if (_nextTaskProcessor != null) { _nextTaskProcessor.addTask(_nextTask); } else { _processor.addTask(_nextTask); } } } // ---------------------------------------------------------------------- // // ABSTRACT // ---------------------------------------------------------------------- // protected abstract boolean _executeImpl(Processor processor); }