/* * Copyright (C) 2013 Alex Kuiper * * This file is part of PageTurner * * PageTurner is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PageTurner is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PageTurner. If not, see <http://www.gnu.org/licenses/>.* */ package net.nightwhistler.pageturner.scheduling; import android.os.AsyncTask; import jedi.functional.Command; import jedi.functional.Functor; import jedi.option.Option; import net.nightwhistler.ui.UiUtils; import static java.lang.Integer.toHexString; import static jedi.option.Options.none; /** * Subclass of AsyncTask which notifies the scheduler when it's done. * * @param <Params> * @param <Progress> * @param <Result> */ public class QueueableAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Option<Result>> { public static interface QueueCallback { void taskCompleted( QueueableAsyncTask<?,?,?> task, boolean wasCancelled ); } private UiUtils.Action onPreExecutionOperation; private Command<Option<Result>> onPostExecuteOperation; private Command<Option<Result>> onCancelledOperation; private Command<Progress[]> onProgressUpdateOperation; private Functor<Params[], Option<Result>> doInBackgroundFunction; private QueueCallback callback; private boolean cancelRequested = false; @Override protected final void onPreExecute() { this.doOnPreExecute(); } /** * Called before execution. * */ public void doOnPreExecute() { if ( this.onPostExecuteOperation != null ) { this.onPreExecutionOperation.perform(); } } @Override protected final void onProgressUpdate(Progress... values) { this.doOnProgressUpdate( values ); } public void doOnProgressUpdate( Progress... values ) { if ( this.onProgressUpdateOperation != null ) { this.onProgressUpdateOperation.execute( values ); } } /** * Overridden and made final to implement notification. * * Subclasses should override doOnPostExecute() instead. * * @param result */ @Override protected final void onPostExecute(Option<Result> result) { if ( callback != null ) { callback.taskCompleted( this, this.cancelRequested ); } doOnPostExecute(result); } /** * Called when a cancellation is requested. * * Default simply sets a flag and calls cancel() */ public void requestCancellation() { this.cancelRequested = true; this.cancel(true); } public boolean isCancelRequested() { return cancelRequested; } @Override protected final void onCancelled(Option<Result> result) { if ( callback != null ) { callback.taskCompleted( this, this.cancelRequested ); } doOnCancelled (result); } @Override protected final void onCancelled() { onCancelled(null); } public void doOnCancelled(Option<Result> result) { if ( this.onCancelledOperation != null ) { this.onCancelledOperation.execute(result); } } public void setCallback( QueueCallback callback ) { this.callback = callback; } /** * Gets executed on the UI thread. * * Override this to implement your on post-processing operations. * * @param result */ public void doOnPostExecute(Option<Result> result) { if ( this.onPostExecuteOperation != null ) { this.onPostExecuteOperation.execute(result); } } @Override public Option<Result> doInBackground(Params... paramses) { if ( this.doInBackgroundFunction != null ) { return this.doInBackgroundFunction.execute( paramses ); } return none(); } @Override public String toString() { return getClass().getSimpleName() + " (" + toHexString( hashCode() ) + ")"; } /** * Sets the operation to be performed when this task is cancelled. * * @param onCancelledOperation * @return this object */ public QueueableAsyncTask setOnCancelled(Command<Option<Result>> onCancelledOperation) { this.onCancelledOperation = onCancelledOperation; return this; } public QueueableAsyncTask setOnPostExecute(Command<Option<Result>> onPostExecuteOperation) { this.onPostExecuteOperation = onPostExecuteOperation; return this; } public QueueableAsyncTask setDoInBackground(Functor<Params[], Option<Result>> doInBackgroundFunction) { this.doInBackgroundFunction = doInBackgroundFunction; return this; } public void setOnPreExecute(UiUtils.Action onPreExecutionOperation) { this.onPreExecutionOperation = onPreExecutionOperation; } public void setOnProgressUpdate(Command<Progress[]> onProgressUpdateOperation) { this.onProgressUpdateOperation = onProgressUpdateOperation; } }