Пример #1
0
  /** Cache the values entered by the user in VEPs dynamically-displayed on VM start. */
  void cacheArgumentValues() {

    // Collect the value entry panels which correspond to target arguments in the TableTop
    List<ValueEditor> argPanels = getArgumentPanels();

    List<Gem.PartInput> argParts = targetDisplayedGem.getTargetArguments();
    int numArgs = argParts.size();

    // sanity check
    if (numArgs != argPanels.size()) {
      throw new IllegalStateException(
          "Programming Error: matching "
              + numArgs
              + " arguments and "
              + argPanels.size()
              + " argument panels.");
    }

    for (int i = 0; i < numArgs; i++) {
      Gem.PartInput argPart = argParts.get(i);
      ValueEditor argPanel = argPanels.get(i);
      ValueNode argNode = argPanel.getValueNode();
      gemCutter.getTableTop().cacheArgValue(argPart, argNode);
    }
  }
Пример #2
0
    private TypeExpr[] getArgTypes() {
      List<ValueEditor> argPanelList = getArgumentPanels();
      TypeExpr[] argTypes = new TypeExpr[argPanelList.size()];
      for (int i = 0, nArgs = argPanelList.size(); i < nArgs; i++) {
        ValueEditor argPanel = argPanelList.get(i);
        argTypes[i] = argPanel.getValueNode().getTypeExpr();
      }

      return argTypes;
    }
Пример #3
0
    private InputPolicy[] getInputPolicies() {
      List<ValueEditor> argPanelList = getArgumentPanels();
      InputPolicy[] ips = new InputPolicy[argPanelList.size()];
      for (int i = 0, nArgs = argPanelList.size(); i < nArgs; i++) {
        ValueEditor argPanel = argPanelList.get(i);
        ips[i] = argPanel.getValueNode().getInputPolicy();
      }

      return ips;
    }
Пример #4
0
    /** {@inheritDoc} */
    @Override
    public void valueCommitted(ValueEditorEvent evt) {
      ValueEditor committedEditor = (ValueEditor) evt.getSource();

      ValueNode oldValue = evt.getOldValue();
      ValueNode newValue = committedEditor.getValueNode();

      if (!oldValue.sameValue(newValue)) {
        switchValueNodeTypeExpr(oldValue, newValue);
        committedEditor.setSize(committedEditor.getPreferredSize());
      }
    }
Пример #5
0
    private Object[] getRuntimeArgumentValues() {

      List<ValueEditor> argPanelList = getArgumentPanels();
      ArrayList<Object> inputJavaValues = new ArrayList<Object>();

      for (int i = 0, nArgs = argPanelList.size(); i < nArgs; i++) {
        ValueEditor argPanel = argPanelList.get(i);
        Object[] values = argPanel.getValueNode().getInputJavaValues();
        for (final Object value : values) {
          inputJavaValues.add(value);
        }
      }
      return inputJavaValues.toArray();
    }
Пример #6
0
  /** Clears the data types and values of the arguments of the running gem */
  void resetArgumentValues() {
    // Loop thru the ValueEditors and reset their ValueNodes.
    for (final ValueEditor editor : valueEditorHierarchyManager.getTopValueEditors()) {

      // build the new ValueNode and give it to the argument panel
      TypeExpr leastConstrainedType = editor.getContext().getLeastConstrainedTypeExpr();
      ValueNode newNode =
          valueEditorHierarchyManager
              .getValueEditorManager()
              .getValueNodeBuilderHelper()
              .getValueNodeForTypeExpr(leastConstrainedType);

      editor.changeOwnerValue(newNode);
    }
  }
Пример #7
0
  /** This method is called when the runtime is about to start evaluating. */
  @Override
  public void enterRunningState() {
    List<ValueEditor> argPanelList = getArgumentPanels();

    // If there are argument panels, we use these to specialize the target
    // type.
    int nPanels = argPanelList.size();
    TypeExpr[] argPanelTypes = new TypeExpr[nPanels];
    for (int i = 0; i < nPanels; i++) {
      ValueEditor argPanel = argPanelList.get(i);
      argPanelTypes[i] = argPanel.getValueNode().getTypeExpr();
    }

    gemCutter.getStatusMessageDisplayer().clearMessage(this);
    gemCutter.setTargetRunningButtons(true);

    // System.out.println ("DisplayedGemRunner.run()");
  }
Пример #8
0
    /**
     * Positions the given value editor next to the connection point for the given input.
     *
     * @param editor the editor to position
     * @param inputPart the input part to position it next to
     */
    private void positionEditor(ValueEditor editor, Gem.PartInput inputPart) {

      // Determine position of the panel and make sure it will be within the parent
      Point xy =
          gemCutter.getTableTop().getDisplayedPartConnectable(inputPart).getConnectionPoint();

      editor.setSize(editor.getPreferredSize());

      // Make sure this is OK
      xy.x -= editor.getWidth();
      xy.y -= editor.getHeight() / 2;
      if (xy.x <= 0) {
        xy.x = 0;
      }
      if (xy.y <= 0) {
        xy.y = 0;
      }

      editor.setLocation(xy);
    }
Пример #9
0
    /**
     * This is used for switching the type of a ValueNode within a given context. Basically, a
     * switch is made between valueNode and newValueNode, but their types are different.
     * Consequently, other valueNodes may be modified.
     *
     * <p>For example:
     *
     * <p>Let's say you have "add 1 2", where 1, 2 are of type Integer and are represented by
     * ValueNodes, then to switch '1' to '1.0' (a Double), you must switch '2' to '2.0' to avoid
     * type clashes.
     *
     * <p>This method will handle the switching of the associated types within a type context, so it
     * should so if you pass 1, 1.0 it'll convert 2 to 2.0 .
     *
     * <p>Note that you are able to pass in '5.0' as the new value if you'd like.
     *
     * @param oldValueNode your original ValueNode
     * @param newValueNode the valueNode that you want to arrive at
     */
    private void switchValueNodeTypeExpr(ValueNode oldValueNode, ValueNode newValueNode) {

      // Create the map from input to value node
      Map<PartInput, ValueNode> inputToValueNodeMap = new HashMap<PartInput, ValueNode>();
      for (final PartInput input : inputToEditorMap.keySet()) {
        ValueEditor editor = inputToEditorMap.get(input);
        inputToValueNodeMap.put(input, editor.getOwnerValueNode());
      }

      // Create the type switcher
      InputValueTypeSwitchHelper switcher =
          new InputValueTypeSwitchHelper(valueEditorManager.getValueNodeCommitHelper());

      // Get the switched values
      Map<PartInput, ValueNode> inputNewValueMap =
          switcher.getInputSwitchValues(oldValueNode, newValueNode, inputToValueNodeMap);

      // Now update with the switched values.
      for (final Map.Entry<PartInput, ValueNode> mapEntry : inputNewValueMap.entrySet()) {
        Gem.PartInput input = mapEntry.getKey();
        ValueNode newInputValue = mapEntry.getValue();

        ValueEditor editor = inputToEditorMap.get(input);

        editor.changeOwnerValue(newInputValue);
        editor.setSize(editor.getPreferredSize());
      }
    }
Пример #10
0
    /**
     * Display value entry controls for all unbound arguments. Precondition: the target must be set.
     */
    private void displayArgumentControls() {

      TableTopPanel tableTopPanel = getTableTopPanel();

      // Build the list of value entry panels and place them onto the TableTop

      // Get the list of unbound arguments
      List<Gem.PartInput> argParts = targetDisplayedGem.getTargetArguments();

      // see if it's ok to use the cached argument values
      boolean canUseCachedArgs = canUseCachedArguments();

      // Figure out the types of the argument panels.  Note that we must account for cached values
      int numArgs = argParts.size();

      // make copies of the input types.
      TypeExpr[] inputTypes = new TypeExpr[numArgs];
      for (int i = 0; i < numArgs; i++) {
        // Get this input, and its type
        Gem.PartInput inputPart = argParts.get(i);
        inputTypes[i] = inputPart.getType();
      }

      TypeExpr[] specializedInputTypes;

      if (canUseCachedArgs) {

        // this is the array of types cached for each argument. If there is no cached type, we just
        // use the argument type.
        TypeExpr[] cachedTypes = new TypeExpr[numArgs];
        for (int i = 0; i < numArgs; ++i) {
          // What we do next depends on whether we use cached sink values
          Gem.PartInput inputPart = argParts.get(i);
          ValueNode cachedVN = gemCutter.getTableTop().getCachedValue(inputPart);
          if (cachedVN != null) {
            cachedTypes[i] = cachedVN.getTypeExpr();
          }
        }

        try {
          ModuleTypeInfo contextModuleTypeInfo =
              gemCutter.getPerspective().getWorkingModuleTypeInfo();
          specializedInputTypes =
              TypeExpr.patternMatchPieces(cachedTypes, inputTypes, contextModuleTypeInfo);
        } catch (TypeException te) {
          throw new IllegalStateException("Error reusing cached args.");
        }
      } else {
        specializedInputTypes = TypeExpr.copyTypeExprs(inputTypes);
      }

      ValueEditorManager valueEditorManager = gemCutter.getValueEditorManager();
      ValueEditorDirector valueEditorDirector = valueEditorManager.getValueEditorDirector();

      Map<PartInput, ValueEditor> inputToEditorMap = new LinkedHashMap<PartInput, ValueEditor>();

      // Step through args, create a new value input panel for each, with the correct value type
      for (int i = 0; i < numArgs; i++) {

        // Get the gem and input
        final Gem.PartInput inputPart = argParts.get(i);
        final Gem inputGem = inputPart.getGem();

        int argumentNumber = inputPart.getInputNum();
        QualifiedName scName = null;

        if (inputGem instanceof FunctionalAgentGem) {
          scName = ((FunctionalAgentGem) inputGem).getName();
        }

        // What we do next depends on whether we use cached sink values
        ValueNode cachedVN;
        final ValueEditor editor;
        if (canUseCachedArgs
            && (cachedVN = gemCutter.getTableTop().getCachedValue(inputPart)) != null) {
          // use cached sink value to generate the VEP

          // get a copy of the cached VN but with the new type expr
          ValueNode newVN = cachedVN.copyValueNode();

          // instantiate the VEP with the new VN (which has the old cached value)
          editor =
              valueEditorDirector.getRootValueEditor(
                  valueEditorHierarchyManager,
                  newVN,
                  scName,
                  argumentNumber,
                  new GemCutterMetadataRunner(gemCutter, inputGem));

        } else {
          // don't use cached sink value.  Generate the default VEP for this sink.
          TypeExpr inputType = specializedInputTypes[i];
          editor =
              valueEditorDirector.getRootValueEditor(
                  valueEditorHierarchyManager,
                  inputType,
                  scName,
                  argumentNumber,
                  new GemCutterMetadataRunner(gemCutter, inputGem));
        }

        // If this is a value entry panel then set the name of the input for use in tooltips
        if (editor instanceof ValueEntryPanel) {
          ((ValueEntryPanel) editor)
              .setArgumentName(inputPart.getArgumentName().getCompositeName());
        }

        // Position the editor next to the connection point.
        positionEditor(editor, inputPart);

        // Now add the editor to the table top.
        tableTopPanel.add(editor, 0);

        // Add to the list of active entry panels
        valueEditorHierarchyManager.addTopValueEditor(editor);

        // Update the context and editor map
        editor.setContext(
            new ValueEditorContext() {
              public TypeExpr getLeastConstrainedTypeExpr() {
                return inputPart.getType();
              }
            });
        inputToEditorMap.put(inputPart, editor);

        // If the editor resizes because it's value changes, make sure it stays aligned to the
        // connection
        editor.addComponentListener(
            new ComponentAdapter() {
              @Override
              public void componentResized(ComponentEvent e) {
                positionEditor((ValueEditor) e.getComponent(), inputPart);
              }
            });
      }

      // Must prevent ValueGems from being editable.
      tableTopPanel.setValueGemsEnabled(false);

      // Need to activate the value editor hierarchy to ensure correct highlighting.
      valueEditorHierarchyManager.activateCurrentEditor();

      // Set the context and type switch listener for each new editor.
      ArgumentValueCommitter argumentValueCommitter =
          new ArgumentValueCommitter(valueEditorManager, inputToEditorMap);

      for (final ValueEditor argumentEditor : getArgumentPanels()) {
        argumentEditor.addValueEditorListener(argumentValueCommitter);
      }

      // May need to show argument controls.
      if (numArgs > 0) {
        gemCutter.showArgumentControls(inputToEditorMap);
        gemCutter.getResetAction().setEnabled(true);
      } else {
        gemCutter.getResetAction().setEnabled(false);
      }
    }