org.ftccommunity.ftcxtensible.robot.RobotContext.java Source code

Java tutorial

Introduction

Here is the source code for org.ftccommunity.ftcxtensible.robot.RobotContext.java

Source

/*
 * Copyright  2015 David Sargent
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the Software?), to deal in the Software without restriction,
 * including without limitation  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and  to permit persons to whom the Software is furnished to
 * do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED AS IS?, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package org.ftccommunity.ftcxtensible.robot;

import android.app.Activity;
import android.content.Context;
import android.util.Log;

import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.MoreExecutors;
import com.qualcomm.robotcore.hardware.Gamepad;
import com.qualcomm.robotcore.hardware.HardwareMap;
import com.qualcomm.robotcore.robocol.Telemetry;

import org.ftccommunity.ftcxtensible.networking.ServerSettings;
import org.ftccommunity.ftcxtensible.sensors.camera.CameraManager;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import io.netty.handler.codec.http.multipart.InterfaceHttpData;

public class RobotContext {
    private ExtensibleHardwareMap hardwareMap;
    private Context appContext;
    private Telemetry telemetry;

    private Gamepad gamepad1;
    private ExtensibleGamepad extensibleGamepad1;
    private Gamepad gamepad2;
    private ExtensibleGamepad extensibleGamepad2;

    private ServerSettings serverSettings;
    private RobotStatus status;
    private CameraManager cameraManager;

    private NetworkedOpMode networkedOpMode;
    private boolean networkingEnabled;

    private LinkedList<InterfaceHttpData> postedData;

    private ExecutorService asyncService;
    private RobotLogger logger;

    private RobotContext() {
        serverSettings = ServerSettings.createServerSettings();
        status = new RobotStatus(this, RobotStatus.LogTypes.HTML);
        postedData = new LinkedList<>();

        extensibleGamepad1 = new ExtensibleGamepad();
        extensibleGamepad2 = new ExtensibleGamepad();

        asyncService = MoreExecutors
                .listeningDecorator(Executors.newCachedThreadPool(MoreExecutors.platformThreadFactory()));
        cameraManager = new CameraManager(this);
        logger = new RobotLogger(this);
    }

    /**
     * Generates OpMode Robot Context item bonded to the normal items in an OpMode
     *
     * @param gp1   opMode reference to Gamepad 1
     * @param gp2   opMode reference to Gamepad 2
     * @param hwMap opMode reference to the Hardware Map
     */
    public RobotContext(Gamepad gp1, Gamepad gp2, HardwareMap hwMap, Telemetry tlmtry) {
        this();
        if (gp1 == null || gp2 == null || hwMap == null) {
            throw new NullPointerException();
        }

        gamepad1 = gp1;
        gamepad2 = gp2;
        hardwareMap = new ExtensibleHardwareMap(hwMap);
        appContext = hwMap.appContext;
        if (appContext == null) {
            try {
                final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
                final Method method = activityThreadClass.getMethod("currentApplication");

                appContext = (Context) method.invoke(null, (Object[]) null);
            } catch (Exception ex) {
                Log.e("ROBOT_CONTEXT::", "Cannot build app context! It will be null.", ex);
            }
        }
        telemetry = tlmtry;
    }

    public RobotContext enableNetworking() {
        if (networkedOpMode == null) {
            networkedOpMode = new NetworkedOpMode(this);
        }
        networkingEnabled = true;

        return this;
    }

    public RobotContext disableNetworking() {
        if (!networkingEnabled || networkedOpMode == null) {
            throw new IllegalStateException("Networking is already disabled!");
        }

        networkedOpMode.stopServer();
        networkedOpMode = null;

        networkingEnabled = false;
        return this;
    }

    public RobotContext startNetworking() {
        if (networkingEnabled && networkedOpMode == null) {
            throw new IllegalStateException("Networking is disabled!");
        }

        networkedOpMode.startServer();
        return this;
    }

    public RobotContext stopNetworking() {
        if (networkingEnabled && networkedOpMode == null) {
            throw new IllegalStateException("Networking is disabled!");
        }

        networkedOpMode.stopServer();
        return this;
    }

    /**
     * Returns the Hardware Map     *
     *
     * @return the <code>ExtensibleHardwareMap</code> currently in use
     */
    public ExtensibleHardwareMap hardwareMap() {
        return hardwareMap;
    }

    /**
     * Binds a new activity context to this
     *
     * @param context a non-null activity context
     * @throws IllegalStateException, IllegalArgumentException
     */
    public void bindAppContext(Context context) throws IllegalArgumentException, IllegalStateException {
        if (context instanceof Activity) {
            /*if (appContext != null) {
            throw new IllegalStateException("Cannot rebind a context when the current context" +
                    " is not null");
            }*/
            appContext = context;
        } else {
            throw new IllegalArgumentException("Invalid context; it must be of an activity context type");
        }
    }

    /**
     * Returns an App Context
     *
     * @return the Android Context
     */
    public Context getAppContext() {
        return appContext;
    }

    /**
     * Returns opMode reference to the first gamepad
     *
     * @return the first gamepad
     * @deprecated Please use the xGamepad1 instead
     */
    @Deprecated
    public Gamepad getGamepad1() {
        return gamepad1;
    }

    /**
     * Returns opMode reference to the second gampepad
     *
     * @return the second gamepad
     * @deprecated Please use the xGamepad2 instead
     */
    @Deprecated
    public Gamepad getGamepad2() {
        return gamepad2;
    }

    /**
     * The current HTTP server settings
     *
     * @return <code>ServerSettings</code>
     */
    public ServerSettings getServerSettings() {
        return serverSettings;
    }

    /**
     * An tool for writing to multiple the same message to multiple places
     *
     * @return the current {@link RobotLogger} to use
     */
    public RobotLogger log() {
        return logger;
    }

    /**
     * Submit a Runnable to be ran
     *
     * @param runnable Runnable to run at some time
     */
    public void submitAsyncTask(Runnable runnable) {
        if (runnable != null) {
            asyncService.execute(runnable);
        } else {
            throw new NullPointerException();
        }
    }

    /**
     * Run a {@code Runnable} on the main app thread
     *
     * @param runnable Runnable to run on the UI Thread.
     */
    public void runOnUiThread(Runnable runnable) {
        if (runnable == null) {
            throw new NullPointerException();
        }

        ((Activity) appContext).runOnUiThread(runnable);
    }

    /**
     * The Robot Status Object
     *
     * @return the current status of the robot
     */
    public RobotStatus status() {
        return status;
    }

    /**
     * Add a collection of data received for further processing by user code
     *
     * @param datas a collection of type <code>InterfaceHttpData</code> to be added
     */
    public void addPostData(Collection<InterfaceHttpData> datas) {
        postedData.addAll(datas);
    }

    /**
     * Get a copy of the received data for use
     *
     * @return an <code>ImmutableList</code> that is a copy of the data received via networking
     */
    public ImmutableList<InterfaceHttpData> getPostedData() {
        return ImmutableList.copyOf(postedData);
    }

    /**
     * The telemetry object to be used
     *
     * @return the telemetry as provide by the FTC SDK
     */
    public Telemetry telemetry() {
        return telemetry;
    }

    /**
     * The first Gamepad in the form of an ExtensibleGamepad.
     *
     * @return the first Gamepad (gamepad1) cast to an ExtensibleGamepad
     */
    public ExtensibleGamepad xGamepad1() {
        return extensibleGamepad1;
    }

    /**
     * The second Gamepad in the form of an ExtensibleGamepad
     *
     * @return the second gamepad (gampad2) cast to an ExtensibleGamepad
     */
    public ExtensibleGamepad xGamepad2() {
        return extensibleGamepad2;
    }

    public CameraManager cameraManager() {
        return cameraManager;
    }

    public void release() {
        if (cameraManager != null) {
            cameraManager.stop();
            cameraManager = null;
        }

        if (networkedOpMode != null) {
            disableNetworking();
        }

        if (asyncService != null) {
            asyncService.shutdown();
        }
    }

    /* public LinkedList upstreamPipeline(HardwareDevice device) {
    if (!deviceUpstreamPipeline.containsKey(device)) {
        deviceUpstreamPipeline.put(device, new LinkedList<UpstreamHardwareUpdate>());
    }
    return deviceUpstreamPipeline.get(device);
     }
        
     public LinkedList upstreamPipeline(Collection<HardwareDevice> devices) {
    if (!genericUpstreamPipeline.containsKey(devices)) {
        genericUpstreamPipeline.put(devices, new LinkedList<UpstreamHardwareUpdate>());
    }
    return genericUpstreamPipeline.get(devices);
     }
        
     public void processDevice(HardwareDevice device) {
    if (deviceUpstreamPipeline.containsKey(device)) {
        for (UpstreamHardwareUpdate<HardwareDevice> upstreamHardwareUpdate : deviceUpstreamPipeline.get(device)) {
            upstreamHardwareUpdate.processRead(device, );
        }
    }
     }*/
}