Package components.commchannel

Source Code of components.commchannel.CommunicationChannel

package components.commchannel;

import java.util.Enumeration;
import java.util.Hashtable;

import utils.Semaphore;
import utils.defines.Defines;
import utils.tracer.TraceState;
import utils.tracer.Traceable;

import components.Component;
import components.features.Feature;



/**
* Esta clase implementa un canal de comunicaciones entre el <i>core</i>
* del robot, y sus componentes perif�ricos (sensores, motores, etc). Una
* vez creada una instancia <code>CommunicationChannel</code>, el canal
* deber� abrirse invocando a <code>open</code> antes de poder ser utilizado.
* De igual forma, el canal deber� ser cerrado mediante <code>close</code>,
* para permitirle la liberaci�n de recursos tomados. <br><br>
*
* El robot accede a sus <i>features</i> a trav�s del canal de comunicaciones.
* Mediante el m�todo <code>receive</code>, obtiene los valores actuales,
* mientras que el m�todo <code>send</code> le permite enviar datos a los
* <i>features</i> (por ejemplo, a los motores para controlar el avance) de
* acuerdo a un protocolo prestablecido. <br><br>
*
* Un canal de comunicaciones se caracteriza por un nombre, una descripci�n,
* y una instancia <code>Robot</code> asociada. <br><br>
*
* Esta clase no puede ser instanciada (necesariamente, deber� extenderse).
*/
public abstract class CommunicationChannel extends Component implements Runnable, Traceable
{
 
  // Constantes
  public static final String      FRONT_SENSOR_NAME  = "FRONT_SENSOR";
  public static final String      LEFT_SENSOR_NAME  = "LEFT_SENSOR";
  public static final String      RIGHT_SENSOR_NAME  = "RIGHT_SENSOR";
  public static final String      COLOR_SENSOR_NAME  = "COLOR_SENSOR";


  private Semaphore          commChannelSemaphore;
  private boolean            closed;
  private Thread            thread;
 
  protected CommunicationChannelState  features;   
 
 
 

  /**
   * Construye un nuevo canal de comunicaciones con nombre y descripci�n
   * nulos, y no asociado a ning�n robot.
   */
  public CommunicationChannel()
  {
    super();
   
    this.thread          = null;
    this.closed          = true;
    this.features        = new CommunicationChannelState();
    this.features.featuresHash  = new Hashtable(11);
    this.commChannelSemaphore  = null;
  }

 
  /**
   * Construye un nuevo canal de comunicaciones con nombre <code>name</code>,
   * descripci�n <code>description</code>, y asociado al robot
   * <code>robot</code>.
   * @param name      nombre.
   * @param description  descripci�n.
   */
  public CommunicationChannel(String name, String description)
  {
    super(name, description);
   
    this.thread          = null;
    this.closed          = true;
    this.features        = new CommunicationChannelState();
    this.features.featuresHash  = new Hashtable(11);
    this.commChannelSemaphore  = null;
  }
 
 
  /**
   * Establece el sem�foro de sincronismo entre este canal y su robot
   * asociado.
   * @param sem sem�foro de sincronismo.
   */
  public final void setCommChannelSemaphore(Semaphore sem)
  {
    commChannelSemaphore = sem;
  }

 
  /**
   * Retorna una referencia al sem�foro de sincronismo entre este canal
   * y su robot asociado.
   * @return sem�foro de sincronismo.
   */
  public final Semaphore getCommChannelSemaphore()
  {
    return commChannelSemaphore;
  }


  /**
   * Abre el canal de comunicaciones. Este m�todo debe ser invocado antes
   * de enviar o recibir datos a trav�s del mismo.
   * @return  <code>OK</code> si se pudo abrir con �xito, o <code>ERROR</code>
   *       en caso contrario.
   */
  public int open(String connectionString)
  {
    if ( !closed )
      // Ya est� abierto
      return Defines.ERROR;
   
    // Crea el thread y lo lanza
    thread = new Thread( this );
    thread.start();
   
    closed  = false;
    return Defines.OK;
  }

 
  /**
   * Cierra el canal de comunicaciones. Este m�todo debe ser invocado cuando
   * el canal ya no est� en uso, para permitirle liberar recursos tomados.
   * @return  <code>OK</code> si se pudo cerrar con �xito, o <code>ERROR</code>
   *       en caso contrario.
   */
  public int close()
  {
    closed  = true;
    return Defines.OK;
  }
 
 
  /**
   * Determina si el canal est� abierto.
   * @return  <code>true</code> si el canal est� abierto, o <code>false</code>
   *       en caso contrario.
   */
  public final boolean isClosed()
  {
    return closed;
  }


  /**
   * Retorna los �ltimos valores le�dos, por el canal, desde los <i>features
   * </i> del robot (sensores, motores, etc.).
   * Estos valores se mantienen en un <i>buffer</i> interno del canal de
   * comunicaciones, y se retornan como una instancia <code>Hashtable</code>.
   * Para extraer los datos desde este hash, deber�n utilizarse los nombres
   * definidos como constantes (
   * {@link #FRONT_SENSOR_NAME FRONT_SENSOR_NAME},
   * {@link #LEFT_SENSOR_NAME LEFT_SENSOR_NAME},
   * {@link #RIGHT_SENSOR_NAME RIGHT_SENSOR_NAME},
   * {@link #COLOR_SENSOR_NAME COLOR_SENSOR_NAME}, etc).
   * @return  instancia <code>Hashtable</code> con los valores de los
   *       <i>features</i>.
   */
  public abstract Hashtable receive();
   
 
  /**
   * Env�a un mensaje que, de acuerdo a un protocolo prestablecido, permite
   * establecer valores en los <i>features</i> que conforman el robot (por
   * ejemplo, control de motores).
   * @param msg valores a establecer seg�n el protocolo prestablecido.
   */
  public abstract void send(String msg);
 
 
  /**
   * Verifica el funcionamiento del canal de comunicaciones.
   * @return  <code>true</code> si el canal funciona correctamente, o
   *       <code>false</code> en caso contrario.
   */
  public abstract boolean test();
 
 
  /**
   * Registra el objeto <code>feature</code> para que el canal
   * pueda actualizarlo cuando recibe nuevos valores desde el robot.
   * @param feature  <code>feature</code> a registrar.
   * @throws CommunicationChannelException  si el <code>feature</code> ya
   *                       fue registrado anteriormente.
   */
  public final void registerFeature(Feature feature) throws CommunicationChannelException
  {
    if ( features.featuresHash.containsKey(feature.getName()) )
      throw new CommunicationChannelException("El objeto " +
                          feature.getName() +
                          " ya fue registrado!");
    features.featuresHash.put(feature.getName(), feature);
  }
 
 
  public synchronized void setCommunicationChannelState(TraceState state)
  {
    CommunicationChannelState commState = (CommunicationChannelState)state;
   
    if ( commState == null  ||  commState.featuresHash == null )
      return;
   
    if ( features != null  &&  features.featuresHash != null )
    {
      for (Enumeration e = commState.featuresHash.keys(); e.hasMoreElements(); )
      {
        String featureName  = (String)e.nextElement();
        Feature feature    = (Feature)commState.featuresHash.get( featureName );
        Object value    = feature.getValue();
       
        feature        = (Feature)features.featuresHash.get( featureName );
       
        if ( feature != null )
          feature.setValue( value );
      }
    }
  }


  public synchronized TraceState getTraceableState()
  {
    return (TraceState)features.clone();
  }
 
 
  public void dispose()
  {
    if ( !isClosed() )
      close();
  }


  public boolean isDisposed()
  {
    return isClosed();
  }
 
 
  public void join()
  {
    try
    {
      if ( thread != null )
        thread.join( 3000 );
    }
    catch (InterruptedException e)
    { }
  }

}
TOP

Related Classes of components.commchannel.CommunicationChannel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.