// Path: core/src/main/java/cat/ppicas/framework/task/Task.java
// public interface Task<R, E extends Exception> {
// 
//     TaskResult<R, E> execute();
// 
// }
// 
// Path: core/src/main/java/cat/ppicas/framework/task/TaskCallback.java
// public interface TaskCallback<R, E extends Exception> {
// 
//     void onSuccess(R result);
// 
//     void onError(E error);
// 
// }
// 
// Path: core/src/main/java/cat/ppicas/framework/task/TaskExecutor.java
// public interface TaskExecutor {
// 
//     <R, E extends Exception> void execute(Task<R, E> task, TaskCallback<R, E> callback);
// 
//     boolean isRunning(Task<?, ?> task);
// 
// }
// 
// Path: core/src/main/java/cat/ppicas/framework/task/TaskResult.java
// public class TaskResult<R, E extends Exception> {
// 
//     private final R mResult;
// 
//     private final E mError;
// 
//     private final boolean mCanceled;
// 
//     public static <R, E extends Exception> TaskResult<R, E> newSuccessResult(R result) {
//         return new TaskResult<>(result, null, false);
//     }
// 
//     public static <R, E extends Exception> TaskResult<R, E> newErrorResult(E error) {
//         return new TaskResult<>(null, error, false);
//     }
// 
//     public static <R, E extends Exception> TaskResult<R, E> newCanceledResult() {
//         return new TaskResult<>(null, null, true);
//     }
// 
//     TaskResult(R result, E error, boolean canceled) {
//         mResult = result;
//         mError = error;
//         mCanceled = canceled;
//     }
// 
//     public R getResult() {
//         return mResult;
//     }
// 
//     public E getError() {
//         return mError;
//     }
// 
//     public boolean isSuccess() {
//         return !mCanceled && mError == null;
//     }
// 
//     public boolean isCanceled() {
//         return mCanceled;
//     }
// }


import android.os.Handler;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import cat.ppicas.framework.task.Task;
import cat.ppicas.framework.task.TaskCallback;
import cat.ppicas.framework.task.TaskExecutor;
import cat.ppicas.framework.task.TaskResult;
/*
 * Copyright (C) 2015 Pau Picas Sans <pau.picas@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package cat.ppicas.cleanarch.util;




/**
 * A {@link TaskExecutor} implementation that executes tasks on another thread. This class
 * will not execute various {@link Task} concurrently. Instead the tasks will be added to the
 * queue and execute one by one respecting the execution order.
 */
public class AsyncTaskExecutor implements TaskExecutor {

    private final Executor mExecutor = Executors.newSingleThreadExecutor();

    private final Handler mHandler = new Handler();

    private final List<WeakReference<?>> mRunningTasks = new ArrayList<>();

    @Override
    public <R, E extends Exception> void execute(
            final Task<R, E> task, final TaskCallback<R, E> callback) {

        addRunningTask(task);
        mExecutor.execute(new Runnable() {
            @Override
            public void run() {
// Path: core/src/main/java/cat/ppicas/framework/task/Task.java
// public interface Task<R, E extends Exception> {
// 
//     TaskResult<R, E> execute();
// 
// }
// 
// Path: core/src/main/java/cat/ppicas/framework/task/TaskCallback.java
// public interface TaskCallback<R, E extends Exception> {
// 
//     void onSuccess(R result);
// 
//     void onError(E error);
// 
// }
// 
// Path: core/src/main/java/cat/ppicas/framework/task/TaskExecutor.java
// public interface TaskExecutor {
// 
//     <R, E extends Exception> void execute(Task<R, E> task, TaskCallback<R, E> callback);
// 
//     boolean isRunning(Task<?, ?> task);
// 
// }
// 
// Path: core/src/main/java/cat/ppicas/framework/task/TaskResult.java
// public class TaskResult<R, E extends Exception> {
// 
//     private final R mResult;
// 
//     private final E mError;
// 
//     private final boolean mCanceled;
// 
//     public static <R, E extends Exception> TaskResult<R, E> newSuccessResult(R result) {
//         return new TaskResult<>(result, null, false);
//     }
// 
//     public static <R, E extends Exception> TaskResult<R, E> newErrorResult(E error) {
//         return new TaskResult<>(null, error, false);
//     }
// 
//     public static <R, E extends Exception> TaskResult<R, E> newCanceledResult() {
//         return new TaskResult<>(null, null, true);
//     }
// 
//     TaskResult(R result, E error, boolean canceled) {
//         mResult = result;
//         mError = error;
//         mCanceled = canceled;
//     }
// 
//     public R getResult() {
//         return mResult;
//     }
// 
//     public E getError() {
//         return mError;
//     }
// 
//     public boolean isSuccess() {
//         return !mCanceled && mError == null;
//     }
// 
//     public boolean isCanceled() {
//         return mCanceled;
//     }
// }


// Path: app/src/main/java/cat/ppicas/cleanarch/util/AsyncTaskExecutor.java
import android.os.Handler;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import cat.ppicas.framework.task.Task;
import cat.ppicas.framework.task.TaskCallback;
import cat.ppicas.framework.task.TaskExecutor;
import cat.ppicas.framework.task.TaskResult;

/*
 * Copyright (C) 2015 Pau Picas Sans <pau.picas@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package cat.ppicas.cleanarch.util;




/**
 * A {@link TaskExecutor} implementation that executes tasks on another thread. This class
 * will not execute various {@link Task} concurrently. Instead the tasks will be added to the
 * queue and execute one by one respecting the execution order.
 */
public class AsyncTaskExecutor implements TaskExecutor {

    private final Executor mExecutor = Executors.newSingleThreadExecutor();

    private final Handler mHandler = new Handler();

    private final List<WeakReference<?>> mRunningTasks = new ArrayList<>();

    @Override
    public <R, E extends Exception> void execute(
            final Task<R, E> task, final TaskCallback<R, E> callback) {

        addRunningTask(task);
        mExecutor.execute(new Runnable() {
            @Override
            public void run() {
                final TaskResult<R, E> result = task.execute();