예제 #1
0
  /** Spawn a thread to wait for all the Being threads to finish. */
  private void joinBeingsTasks() {
    // First, initialize mExitBarrier that's used as an exit
    // barrier to ensure the waiter thread doesn't finish until
    // all the BeingTasks finish.
    mExitBarrier = new CountDownLatch(Options.instance().numberOfBeings());

    // Create/start a waiter thread that uses mExitBarrier to wait
    // for all the BeingTasks to finish.  After they are all
    // finished then tell the UI thread this simulation is done.
    new Thread(
            new Runnable() {
              @Override
              public void run() {
                try {
                  // Wait for all BeingTasks to stop gazing.
                  mExitBarrier.await();
                } catch (Exception e) {
                  Log.d(TAG, "joinBeingTasks() received exception");
                  // If we get interrupted while waiting, stop
                  // everything.
                  shutdown();
                } finally {
                  // Tell the UI thread this simulation is done.
                  mView.get().done();
                }
              }
            })
        .start();
  }
예제 #2
0
  /**
   * This method is called each time a Being acquires a Palantir. Since each Being is a Java Thread,
   * it will be called concurrently from different threads. This method increments the number of
   * threads gazing and checks that the number of threads gazing does not exceed the number of
   * Palantiri in the simulation using an AtomicLong object instantiated above (mGazingThreads). If
   * the number of gazing threads exceeds the number of Palantiri, this thread will call shutdown
   * and return false.
   *
   * @return false if the number of gazing threads is greater than the number of Palantiri,
   *     otherwise true.
   */
  private boolean incrementGazingCountAndCheck(PalantiriPresenter presenter) {
    final long numberOfGazingThreads = presenter.mGazingTasks.incrementAndGet();

    if (numberOfGazingThreads > Options.instance().numberOfPalantiri()) {
      presenter.shutdown();
      return false;
    } else return true;
  }
예제 #3
0
  /**
   * This method is called when the user asks to start the simulation in the context of the main UI
   * Thread. It creates the designated number of Palantiri and adds them to the PalantiriManager. It
   * then creates a Thread for each Being and has each Being attempt to acquire a Palantir for
   * gazing, mediated by the PalantiriManager. The BeingTheads call methods from the
   * MVP.RequiredViewOps interface to visualize what is happening to the user.
   */
  @Override
  public void start() {
    // Initialize the Palantiri.
    getModel().makePalantiri(Options.instance().numberOfPalantiri());

    // Initialize the count of the number of threads Beings use to gaze.
    mGazingTasks = new AtomicLong(0);

    // Show the Beings on the UI.
    mView.get().showBeings();

    // Show the palantiri on the UI.
    mView.get().showPalantiri();

    // Spawn a thread that waits for all the Being threads to finish.
    joinBeingsTasks();

    // Create and execute an AsyncBeingTask for each Being.
    Log.i(TAG, "Before createAndExecuteBeingsTasks");
    createAndExecuteBeingsTasks(Options.instance().numberOfBeings());
    Log.i(TAG, "After createAndExecuteBeingsTasks");
  }
예제 #4
0
  /**
   * This method is called when the user asks to start the simulation in the context of the main UI
   * Thread. It creates the designated number of Palantiri and adds them to the PalantiriManager. It
   * then creates a Thread for each Being and has each Being attempt to acquire a Palantir for
   * gazing, mediated by the PalantiriManager. The BeingTheads call methods from the
   * MVP.RequiredViewOps interface to visualize what is happening to the user.
   */
  @Override
  public void start() {
    // Initialize the PalantiriManager.
    getModel().makePalantiri(Options.instance().numberOfPalantiri());

    // Initialize the count of the number of threads Beings use to
    // gaze.
    mGazingThreads = new AtomicLong(0);

    // Show the Beings on the UI.
    mView.get().showBeings();

    // Show the palantiri on the UI.
    mView.get().showPalantiri();

    // Create and start a BeingThread for each Being.
    beginBeingsThreads(Options.instance().numberOfBeings());

    // Start a thread to wait for all the Being threads to finish
    // and then inform the View layer that the simulation is done.
    waitForBeingsThreads();
  }
예제 #5
0
  /**
   * Hook method called when a new instance of PalantiriPresenter is created. One time
   * initialization code goes here, e.g., storing a WeakReference to the View layer and initializing
   * the Model layer.
   *
   * @param view A reference to the View layer.
   */
  @Override
  public void onCreate(MVP.RequiredViewOps view) {
    // Set the WeakReference.
    mView = new WeakReference<>(view);

    // Invoke the special onCreate() method in GenericPresenter,
    // passing in the PalantiriModel class to instantiate/manage
    // and "this" to provide this MVP.RequiredModelOps instance.
    super.onCreate(PalantiriModel.class, this);

    // Get the intent used to start the Activity.
    final Intent intent = view.getIntent();

    // Initialize the Options singleton using the extras contained
    // in the intent.
    if (Options.instance().parseArgs(view.getActivityContext(), makeArgv(intent)) == false)
      Utils.showToast(view.getActivityContext(), "Arguments were incorrect");

    // A runtime configuration change has not yet occurred.
    mConfigurationChangeOccurred = false;
  }
예제 #6
0
  /** Perform the Being gazing logic. */
  @Override
  public Void doInBackground(PalantiriPresenter... presenters) {
    // Don't start the threads immediately.
    Utils.pauseThread(500);

    // Initialize local variables.
    int i = 0;
    Palantir palantir = null;
    final PalantiriPresenter presenter = presenters[0];

    // Try to gaze at a palantir the designated number of times.
    for (; i < Options.instance().gazingIterations(); ++i)
      try {
        // Break out of the loop if the BeingAsyncTask has
        // been cancelled.
        // you fill in here by replacing "false" with
        // the appropriate method call to an AsyncTask method.
        if (isCancelled()) {
          // If we've been instructed to stop gazing, notify
          // the UI and exit gracefully.
          presenter.mView.get().threadShutdown(mIndex);
          break;
        }

        // Show that we're waiting on the screen.
        // you fill in here with the appropriate
        // call to an AsyncTask method.
        publishProgress(presenter.mView.get().markWaiting(mIndex));
        // Get a Palantir - this call blocks if there are no
        // available Palantiri.
        palantir = presenter.getModel().acquirePalantir();

        if (palantir == null)
          Log.d(
              TAG,
              "Received a null palantir in "
                  + Thread.currentThread().getId()
                  + " for Being "
                  + mIndex);

        // Make sure we were supposed to get a Palantir.
        if (!incrementGazingCountAndCheck(presenter)) break;

        // Mark it as used on the screen.
        // you fill in here with the appropriate
        // call to an AsyncTask method.
        publishProgress(presenter.mView.get().markUsed(palantir.getId()));
        // Show that we're gazing on the screen.
        // you fill in here with the appropriate
        // call to an AsyncTask method.
        publishProgress(presenter.mView.get().markGazing(mIndex));
        // Gaze at my Palantir for the alloted time.
        palantir.gaze();

        // Show that we're no longer gazing.
        // you fill in here with the appropriate
        // call to an AsyncTask method.
        publishProgress(presenter.mView.get().markIdle(mIndex));
        Utils.pauseThread(500);

        // Mark the Palantir as being free.
        // you fill in here with the appropriate call
        // to an AsyncTask method.
        publishProgress(presenter.mView.get().markFree(palantir.getId()));
        Utils.pauseThread(500);

        // Tell the double-checker that we're about to
        // give up a Palantir.
        decrementGazingCount(presenter);
      } catch (Exception e) {
        Log.d(TAG, "Exception caught in index " + mIndex);

        // If we're interrupted by an exception, notify the UI and
        // exit gracefully.
        presenter.mView.get().threadShutdown(mIndex);
      } finally {
        // Give it back to the manager.
        presenter.getModel().releasePalantir(palantir);
      }

    Log.d(
        TAG,
        "Thread "
            + mIndex
            + " has finished "
            + i
            + " of its "
            + Options.instance().gazingIterations()
            + " gazing iterations");
    return (Void) null;
  }