Ejemplo n.º 1
0
  /**
   * Generate code for transferring enough tokens to fulfill the output production rate.
   *
   * @param outputPort The port to transfer tokens.
   * @param code The string buffer that the generated code is appended to.
   * @exception IllegalActionException If thrown while transferring tokens.
   */
  public void generateTransferOutputsCode(IOPort outputPort, StringBuffer code)
      throws IllegalActionException {
    code.append(
        CodeStream.indent(
            _codeGenerator.comment("SDFDirector: " + "Transfer tokens to the outside.")));

    int rate = DFUtilities.getTokenProductionRate(outputPort);

    CompositeActor container = (CompositeActor) getComponent().getContainer();
    ptolemy.codegen.c.actor.TypedCompositeActor compositeActorHelper =
        (ptolemy.codegen.c.actor.TypedCompositeActor) _getHelper(container);

    if (container instanceof TypedCompositeActorWithCoSimulation) {

      if (_portNumber == 0) {
        int numberOfOutputPorts = container.outputPortList().size();

        code.append(_INDENT2 + "jobjectArray tokensToAllOutputPorts;" + _eol);
        code.append(
            _INDENT2
                + "jclass objClass = (*env)->FindClass(env, "
                + "\"Ljava/lang/Object;\");"
                + _eol);
        code.append(
            _INDENT2
                + "tokensToAllOutputPorts = "
                + "(*env)->NewObjectArray(env, "
                + numberOfOutputPorts
                + ", objClass, NULL);"
                + _eol);
      }

      String portName = outputPort.getName();
      String tokensToThisPort = "tokensTo" + portName;
      ;
      Type type = ((TypedIOPort) outputPort).getType();

      int numberOfChannels = outputPort.getWidthInside();
      code.append(_INDENT2 + "jobjectArray " + tokensToThisPort + ";" + _eol);

      if (type == BaseType.INT) {
        if (!_intFlag) {
          code.append(_INDENT2 + "jclass objClassI = (*env)->FindClass(env, " + "\"[I\");" + _eol);
          _intFlag = true;
        }
        code.append(
            _INDENT2
                + tokensToThisPort
                + " = (*env)->NewObjectArray(env, "
                + numberOfChannels
                + ", objClassI, NULL);"
                + _eol);
      } else if (type == BaseType.DOUBLE) {
        if (!_doubleFlag) {
          code.append(_INDENT2 + "jclass objClassD = (*env)->FindClass(env, " + "\"[D\");" + _eol);
          _doubleFlag = true;
        }
        code.append(
            _INDENT2
                + tokensToThisPort
                + " = (*env)->NewObjectArray(env, "
                + numberOfChannels
                + ", objClassD, NULL);"
                + _eol);
      } else {
        // FIXME: need to deal with other types
      }

      for (int i = 0; i < outputPort.getWidthInside(); i++) {

        String tokensToOneChannel = "tokensToOneChannelOf" + portName;
        if (i == 0) {
          if (type == BaseType.INT) {
            code.append(_INDENT2 + "jint " + tokensToOneChannel + "[" + rate + "];" + _eol);

          } else if (type == BaseType.DOUBLE) {
            code.append(_INDENT2 + "jdouble " + tokensToOneChannel + "[" + rate + "];" + _eol);

          } else {
            // FIXME: need to deal with other types
          }
        }

        String portNameWithChannelNumber = portName;
        if (outputPort.isMultiport()) {
          portNameWithChannelNumber = portName + '#' + i;
        }

        for (int k = 0; k < rate; k++) {
          code.append(
              _INDENT2
                  + tokensToOneChannel
                  + "["
                  + k
                  + "] = "
                  + compositeActorHelper.getReference("@" + portNameWithChannelNumber + "," + k)
                  + ";"
                  + _eol);
        }

        String tokensToOneChannelArray = "arr" + portName + i;
        if (type == BaseType.INT) {
          code.append(
              _INDENT2
                  + "jintArray "
                  + tokensToOneChannelArray
                  + " = "
                  + "(*env)->NewIntArray(env, "
                  + rate
                  + ");"
                  + _eol);
          code.append(
              _INDENT2
                  + "(*env)->SetIntArrayRegion"
                  + "(env, "
                  + tokensToOneChannelArray
                  + ", 0, "
                  + rate
                  + ", "
                  + tokensToOneChannel
                  + ");"
                  + _eol);

        } else if (type == BaseType.DOUBLE) {
          code.append(
              _INDENT2
                  + "jdoubleArray "
                  + tokensToOneChannelArray
                  + " = "
                  + "(*env)->NewDoubleArray(env, "
                  + rate
                  + ");"
                  + _eol);
          code.append(
              _INDENT2
                  + "(*env)->SetDoubleArrayRegion"
                  + "(env, "
                  + tokensToOneChannelArray
                  + ", 0, "
                  + rate
                  + ", "
                  + tokensToOneChannel
                  + ");"
                  + _eol);

        } else {
          // FIXME: need to deal with other types
        }

        code.append(
            _INDENT2
                + "(*env)->SetObjectArrayElement"
                + "(env, "
                + tokensToThisPort
                + ", "
                + i
                + ", "
                + tokensToOneChannelArray
                + ");"
                + _eol);
        code.append(
            _INDENT2 + "(*env)->DeleteLocalRef(env, " + tokensToOneChannelArray + ");" + _eol);
      }

      code.append(
          _INDENT2
              + "(*env)->SetObjectArrayElement"
              + "(env, tokensToAllOutputPorts, "
              + _portNumber
              + ", "
              + tokensToThisPort
              + ");"
              + _eol);
      code.append(_INDENT2 + "(*env)->DeleteLocalRef(env, " + tokensToThisPort + ");" + _eol);
      _portNumber++;

    } else {
      for (int i = 0; i < outputPort.getWidthInside(); i++) {
        if (i < outputPort.getWidth()) {
          String name = outputPort.getName();

          if (outputPort.isMultiport()) {
            name = name + '#' + i;
          }

          for (int k = 0; k < rate; k++) {
            code.append(CodeStream.indent(compositeActorHelper.getReference(name + "," + k)));
            code.append(" =" + _eol);
            code.append(
                CodeStream.indent(
                    _INDENT2 + compositeActorHelper.getReference("@" + name + "," + k)));
            code.append(";" + _eol);
          }
        }
      }
    }

    // The offset of the ports connected to the output port is
    // updated by outside director.
    _updatePortOffset(outputPort, code, rate);
  }