Ejemplo n.º 1
0
  /**
   * Transmit the specified token to the specified receiver with the specified properties. If
   * <i>propagationSpeed</i> is less than Infinity, then this results in a call to fireAt() of the
   * director for each receiver that is in range. The token is not actually transmitted to the
   * receiver until the corresponding invocation of fire() occurs. The time delay is equal to
   * distance/<i>propagationSpeed</i>. See the class comments for the assumptions that make this
   * correct.
   *
   * <p>If the <i>lossProbability</i> is zero, (the default) then the specified receiver will
   * receive the token if it has room. If <i>lossProbability</i> is greater than zero, the token
   * will be lost with the specified probability, independently for each receiver in range. Note
   * that in this base class, a port is in range if it refers to this channel by name and is at the
   * right place in the hierarchy. This base class makes no use of the properties argument. But
   * derived classes may limit the range or otherwise change transmission properties using this
   * argument.
   *
   * @param token The token to transmit, or null to clear the specified receiver.
   * @param sender The sending port.
   * @param receiver The receiver to which to transmit.
   * @param properties The transmit properties (ignored in this base class).
   * @exception IllegalActionException If the token cannot be converted or if the token argument is
   *     null and the destination receiver does not support clear.
   */
  protected void _transmitTo(
      Token token, WirelessIOPort sender, WirelessReceiver receiver, RecordToken properties)
      throws IllegalActionException {
    double speed = ((DoubleToken) propagationSpeed.getToken()).doubleValue();

    if (speed == Double.POSITIVE_INFINITY) {
      super._transmitTo(token, sender, receiver, properties);
    } else {
      Director director = getDirector();

      // FIXME: This isn't right because the receiver
      // may have moved during propagation.  Maybe
      // register a ValueListener to the _location attributes
      // of the receiver actors, and continually recalculate
      // the correct arrival time for the message each time the
      // receiver location changes.  Even so, this will be
      // an approximation, and needs to be fully characterized.
      // Also, the receiver needs to be in range at the
      // conclusion of the propagation, whereas this method is
      // called only if the receiver is in range at the
      // initiation of the transmission.
      WirelessIOPort destination = (WirelessIOPort) receiver.getContainer();
      double distance = _distanceBetween(sender, destination);
      Time time = director.getModelTime().add(distance / speed);

      if (_receptions == null) {
        _receptions = new HashMap();
      }

      Double timeDouble = Double.valueOf(time.getDoubleValue());
      Reception reception = new Reception();
      reception.token = token;
      reception.sender = sender;
      reception.receiver = receiver;
      reception.properties = properties;
      _receptions.put(timeDouble, reception);

      _fireAt(time);
    }
  }