/* * Copyright (C) 2011 The Android Open Source Project * * 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 android.filterfw; import android.content.Context; import android.filterfw.core.AsyncRunner; import android.filterfw.core.FilterGraph; import android.filterfw.core.FilterContext; import android.filterfw.core.FrameManager; import android.filterfw.core.GraphRunner; import android.filterfw.core.RoundRobinScheduler; import android.filterfw.core.SyncRunner; import android.filterfw.io.GraphIOException; import android.filterfw.io.GraphReader; import android.filterfw.io.TextGraphReader; import java.util.ArrayList; /** * A GraphEnvironment provides a simple front-end to filter graph setup and execution using the * mobile filter framework. Typically, you use a GraphEnvironment in the following fashion: * 1. Instantiate a new GraphEnvironment instance. * 2. Perform any configuration, such as adding graph references and setting a GL environment. * 3. Load a graph file using loadGraph() or add a graph using addGraph(). * 4. Obtain a GraphRunner instance using getRunner(). * 5. Execute the obtained runner. * Note that it is possible to add multiple graphs and runners to a single GraphEnvironment. * * @hide */ public class GraphEnvironment extends MffEnvironment { public static final int MODE_ASYNCHRONOUS = 1; public static final int MODE_SYNCHRONOUS = 2; private GraphReader mGraphReader; private ArrayList<GraphHandle> mGraphs = new ArrayList<GraphHandle>(); private class GraphHandle { private FilterGraph mGraph; private AsyncRunner mAsyncRunner; private SyncRunner mSyncRunner; public GraphHandle(FilterGraph graph) { mGraph = graph; } public FilterGraph getGraph() { return mGraph; } public AsyncRunner getAsyncRunner(FilterContext environment) { if (mAsyncRunner == null) { mAsyncRunner = new AsyncRunner(environment, RoundRobinScheduler.class); mAsyncRunner.setGraph(mGraph); } return mAsyncRunner; } public GraphRunner getSyncRunner(FilterContext environment) { if (mSyncRunner == null) { mSyncRunner = new SyncRunner(environment, mGraph, RoundRobinScheduler.class); } return mSyncRunner; } } /** * Create a new GraphEnvironment with default components. */ public GraphEnvironment() { super(null); } /** * Create a new GraphEnvironment with a custom FrameManager and GraphReader. Specifying null * for either of these, will auto-create a default instance. * * @param frameManager The FrameManager to use, or null to auto-create one. * @param reader The GraphReader to use for graph loading, or null to auto-create one. * Note, that the reader will not be created until it is required. Pass * null if you will not load any graph files. */ public GraphEnvironment(FrameManager frameManager, GraphReader reader) { super(frameManager); mGraphReader = reader; } /** * Returns the used graph reader. This will create one, if a reader has not been set already. */ public GraphReader getGraphReader() { if (mGraphReader == null) { mGraphReader = new TextGraphReader(); } return mGraphReader; } /** * Add graph references to resolve during graph reading. The references added here are shared * among all graphs. * * @param references An alternating argument list of keys (Strings) and values. */ public void addReferences(Object... references) { getGraphReader().addReferencesByKeysAndValues(references); } /** * Loads a graph file from the specified resource and adds it to this environment. * * @param context The context in which to read the resource. * @param resourceId The ID of the graph resource to load. * @return A unique ID for the graph. */ public int loadGraph(Context context, int resourceId) { // Read the file into a graph FilterGraph graph = null; try { graph = getGraphReader().readGraphResource(context, resourceId); } catch (GraphIOException e) { throw new RuntimeException("Could not read graph: " + e.getMessage()); } // Add graph to our list of graphs return addGraph(graph); } /** * Add a graph to the environment. Consider using loadGraph() if you are loading a graph from * a graph file. * * @param graph The graph to add to the environment. * @return A unique ID for the added graph. */ public int addGraph(FilterGraph graph) { GraphHandle graphHandle = new GraphHandle(graph); mGraphs.add(graphHandle); return mGraphs.size() - 1; } /** * Access a specific graph of this environment given a graph ID (previously returned from * loadGraph() or addGraph()). Throws an InvalidArgumentException if no graph with the * specified ID could be found. * * @param graphId The ID of the graph to get. * @return The graph with the specified ID. */ public FilterGraph getGraph(int graphId) { if (graphId < 0 || graphId >= mGraphs.size()) { throw new IllegalArgumentException( "Invalid graph ID " + graphId + " specified in runGraph()!"); } return mGraphs.get(graphId).getGraph(); } /** * Get a GraphRunner instance for the graph with the specified ID. The GraphRunner instance can * be used to execute the graph. Throws an InvalidArgumentException if no graph with the * specified ID could be found. * * @param graphId The ID of the graph to get. * @param executionMode The mode of graph execution. Currently this can be either MODE_SYNCHRONOUS or MODE_ASYNCHRONOUS. * @return A GraphRunner instance for this graph. */ public GraphRunner getRunner(int graphId, int executionMode) { switch (executionMode) { case MODE_ASYNCHRONOUS: return mGraphs.get(graphId).getAsyncRunner(getContext()); case MODE_SYNCHRONOUS: return mGraphs.get(graphId).getSyncRunner(getContext()); default: throw new RuntimeException( "Invalid execution mode " + executionMode + " specified in getRunner()!"); } } }