/** @author David Culyba */
public class EventCriteriaManager {
  public void addCondition(ManipulationEventCriteria condition) {
    if (!this.manipulationConditions.contains(condition)) {
      this.manipulationConditions.add(condition);
    }
  }

  public void removeCondition(ManipulationEventCriteria condition) {
    this.manipulationConditions.remove(condition);
  }

  public void setTargetTransformable(
      edu.cmu.cs.dennisc.scenegraph.AbstractTransformable transformable) {
    this.targetTransformable = transformable;
  }

  public boolean matches(ManipulationEvent event) {
    if ((this.targetTransformable == null)
        || (event.getTarget() == null)
        || (this.targetTransformable == event.getTarget())) {
      for (ManipulationEventCriteria condition : this.manipulationConditions) {
        if (condition.matches(event)) {
          return true;
        }
      }
    }
    return false;
  }

  private final java.util.List<ManipulationEventCriteria> manipulationConditions =
      edu.cmu.cs.dennisc.java.util.Lists.newCopyOnWriteArrayList();
  private edu.cmu.cs.dennisc.scenegraph.AbstractTransformable targetTransformable;
}
 public static java.util.List<org.lgna.project.ast.NamedUserType> getNamedUserTypesFromSuperTypes(
     java.util.List<org.lgna.project.ast.JavaType> superTypes) {
   java.util.ArrayList<org.lgna.project.ast.NamedUserType> rv =
       edu.cmu.cs.dennisc.java.util.Lists.newArrayListWithInitialCapacity(superTypes.size());
   for (org.lgna.project.ast.JavaType superType : superTypes) {
     rv.add(getNamedUserTypeFromSuperType(superType));
   }
   return rv;
 }
Beispiel #3
0
  public class SwingModel {
    private java.awt.Color value;

    private final java.util.List<javax.swing.event.ChangeListener> changeListeners =
        edu.cmu.cs.dennisc.java.util.Lists.newCopyOnWriteArrayList();

    public SwingModel(java.awt.Color initialValue) {
      this.value = initialValue;
    }

    public java.awt.Color getValue() {
      return this.value;
    }

    public void setValue(java.awt.Color nextValue, java.awt.event.MouseEvent e) {
      if (this.value.equals(nextValue)) {
        // pass
      } else {
        this.value = nextValue;
        IsAdjusting isAdjusting;
        if (e != null) {
          isAdjusting =
              e.getID() != java.awt.event.MouseEvent.MOUSE_RELEASED
                  ? IsAdjusting.TRUE
                  : IsAdjusting.FALSE;
        } else {
          isAdjusting = IsAdjusting.FALSE;
        }

        // todo
        isAdjusting = IsAdjusting.FALSE;

        org.lgna.croquet.triggers.Trigger trigger;
        if (e != null) {
          trigger = org.lgna.croquet.triggers.MouseEventTrigger.createUserInstance(e);
        } else {
          trigger = org.lgna.croquet.triggers.NullTrigger.createUserInstance();
        }
        changeValueFromSwing(this.value, isAdjusting, trigger);
        if (this.changeListeners.size() > 0) {
          Object source = e != null ? e.getSource() : this;
          javax.swing.event.ChangeEvent changeEvent = new javax.swing.event.ChangeEvent(source);
          for (javax.swing.event.ChangeListener changeListener : this.changeListeners) {
            changeListener.stateChanged(changeEvent);
          }
        }
      }
    }

    public void addChangeListener(javax.swing.event.ChangeListener changeListener) {
      this.changeListeners.add(changeListener);
    }

    public void removeChangeListener(javax.swing.event.ChangeListener changeListener) {
      this.changeListeners.remove(changeListener);
    }
  }
  public edu.cmu.cs.dennisc.java.util.zip.DataSource[] getDataSources() {
    edu.cmu.cs.dennisc.java.util.zip.DataSource[] dataSources;
    try {
      final java.awt.image.BufferedImage thumbnailImage = createThumbnail();
      if (thumbnailImage != null) {
        if ((thumbnailImage.getWidth() > 0) && (thumbnailImage.getHeight() > 0)) {
          // pass
        } else {
          throw new RuntimeException();
        }
      } else {
        throw new NullPointerException();
      }
      final byte[] data =
          edu.cmu.cs.dennisc.image.ImageUtilities.writeToByteArray(
              edu.cmu.cs.dennisc.image.ImageUtilities.PNG_CODEC_NAME, thumbnailImage);
      // <lg>
      java.util.List<edu.cmu.cs.dennisc.java.util.zip.DataSource> dataSourcesList =
          edu.cmu.cs.dennisc.java.util.Lists.newArrayList();
      edu.cmu.cs.dennisc.java.util.zip.DataSource thumbnailData =
          new edu.cmu.cs.dennisc.java.util.zip.DataSource() {
            @Override
            public String getName() {
              return "thumbnail.png";
            }

            @Override
            public void write(java.io.OutputStream os) throws java.io.IOException {
              os.write(data);
            }
          };
      dataSourcesList.add(thumbnailData);

      edu.cmu.cs.dennisc.java.util.zip.DataSource originalTypeData =
          getOriginalProgramTypeDataSource();
      if (originalTypeData != null) {
        dataSourcesList.add(originalTypeData);
      }
      edu.cmu.cs.dennisc.java.util.zip.DataSource originalVersionData =
          getOriginalVersionDataSource();
      if (originalVersionData != null) {
        dataSourcesList.add(originalVersionData);
      }
      dataSources =
          edu.cmu.cs.dennisc.java.lang.ArrayUtilities.createArray(
              dataSourcesList, edu.cmu.cs.dennisc.java.util.zip.DataSource.class);
      // </lg>
    } catch (Throwable t) {
      dataSources = new edu.cmu.cs.dennisc.java.util.zip.DataSource[] {};
    }
    return dataSources;
  }
 public static org.lgna.project.ast.AbstractType<?, ?, ?>[] getArgumentTypes(
     org.lgna.project.ast.AbstractType<?, ?, ?> ancestorType,
     org.lgna.project.ast.AbstractType<?, ?, ?> resourceType) {
   java.util.List<org.lgna.project.ast.AbstractType<?, ?, ?>> types =
       edu.cmu.cs.dennisc.java.util.Lists.newLinkedList();
   updateArgumentTypes(
       types,
       ConstructorArgumentUtilities.getContructor0Parameter0Type(ancestorType),
       resourceType);
   org.lgna.project.ast.AbstractType<?, ?, ?>[] rv =
       new org.lgna.project.ast.AbstractType<?, ?, ?>[types.size()];
   types.toArray(rv);
   return rv;
 }
  public GLExceptionPane(Thread thread, Throwable throwable) {
    super(GLExceptionPane.class, thread, throwable);

    DialogOptionButton optionButton =
        new DialogOptionButton(
            getLocalizedString("GLExceptionPane.helpAction"),
            getLocalizedString("GLExceptionPane.helpActionSubtitle"));
    DialogOptionButtonGroup buttonGroup =
        new DialogOptionButtonGroup(
            edu.cmu.cs.dennisc.java.util.Lists.newArrayList(optionButton), optionButton);

    this.optionButtonsContainer.setCenter(buttonGroup);

    this.registerActionEvent(optionButton, optionButton.onActionProperty(), this::handleHelpAction);
  }
  public edu.cmu.cs.dennisc.java.util.zip.DataSource[] getAdditionalDataSources() {
    java.util.List<edu.cmu.cs.dennisc.java.util.zip.DataSource> dataSourcesList =
        edu.cmu.cs.dennisc.java.util.Lists.newArrayList();

    edu.cmu.cs.dennisc.java.util.zip.DataSource originalTypeData =
        getOriginalProgramTypeDataSource();
    if (originalTypeData != null) {
      dataSourcesList.add(originalTypeData);
    }
    edu.cmu.cs.dennisc.java.util.zip.DataSource originalVersionData =
        getOriginalVersionDataSource();
    if (originalVersionData != null) {
      dataSourcesList.add(originalVersionData);
    }
    return edu.cmu.cs.dennisc.java.lang.ArrayUtilities.createArray(
        dataSourcesList, edu.cmu.cs.dennisc.java.util.zip.DataSource.class);
  }
/**
 * An object that receives <code>VMObserver</code> events from the <code>VMObserverManager</code>,
 * processes these events, creates the appropriate <code>EventNode</code>, and then notifies any
 * listeners of statement execution.
 *
 * @author Paul Gross
 */
public class VMExecutionObserver implements VMObserver {

  private boolean isRecording = false;
  private boolean hasInvokedEntryPoint = false;

  private final Map<Object, UserField> instanceMap = Maps.newHashMap();
  private final Set<CurrentExecutionListener> executionListeners = Sets.newHashSet();

  private final java.util.Map<Statement, java.util.ArrayList<AbstractEventNode<?>>>
      statementEventNodes = Maps.newHashMap();
  private final java.util.List<LambdaEventNode> lambdaEventNodes = Lists.newLinkedList();

  private final KeyedStack<ComponentThread, AbstractEventNode<?>> eventNodeStack =
      new KeyedStack<ComponentThread, AbstractEventNode<?>>();
  private AbstractEventNode<?> rootEventNode;
  private UserInstance sceneInstance;

  public VMExecutionObserver(MessagingVirtualMachine virtualMachine) {
    virtualMachine.addObserver(this);
  }

  public void addCurrentExecutionListener(CurrentExecutionListener listener) {
    synchronized (this.executionListeners) {
      this.executionListeners.add(listener);
    }
  }

  public boolean removeCurrentExecutionListener(CurrentExecutionListener listener) {
    synchronized (this.executionListeners) {
      return this.executionListeners.remove(listener);
    }
  }

  public UserInstance getSceneInstance() {
    return this.sceneInstance;
  }

  public boolean eventNodesExistForStatement(Statement statement) {
    java.util.Collection<AbstractEventNode<?>> nodes = this.statementEventNodes.get(statement);
    return (nodes != null) && (nodes.size() > 0);
  }

  public java.util.ArrayList<AbstractEventNode<?>> getEventNodesForStatement(Statement statement) {
    return this.statementEventNodes.get(statement);
  }

  public AbstractEventNode<?> getEventNodeForStatementAtTime(Statement statement, double time) {
    for (AbstractEventNode<?> event : getEventNodesForStatement(statement)) {
      if (event.isExecutingAtTime(time)) {
        return event;
      }
    }
    return null;
  }

  public boolean isRootEventNode(AbstractEventNode<?> eventNode) {
    return (eventNode == this.rootEventNode);
  }

  public AbstractEventNode<?> getRootEventNode() {
    return this.rootEventNode;
  }

  public java.util.List<LambdaEventNode> getLambdaEventNodes() {
    return this.lambdaEventNodes;
  }

  public Map<Object, UserField> getInstanceMap() {
    return this.instanceMap;
  }

  public boolean hasInvokedEntryPoint() {
    return this.hasInvokedEntryPoint;
  }

  public boolean isRecording() {
    return this.isRecording;
  }

  public void setIsRecording(boolean value) {
    this.isRecording = value;
  }

  /**
   * Called when a new {@link VMObservableEvent} is passed. Executes the correct method based on the
   * {@link VMMessage} for the event.
   *
   * @param event {@link VMObservableEvent} passed from {@link VMObserverManager}
   */
  @Override
  public synchronized void update(VMObservableEvent event) {
    VMMessage eventMsg = event.getVMMessage();

    if (eventMsg == VMMessage.START_RECORDING) {
      this.isRecording = true;
    } else if (eventMsg == VMMessage.STOP_RECORDING) {
      this.isRecording = false;
    } else if (eventMsg == VMMessage.CREATE_INSTANCE) {
      if ((event.getProperties().length == 1) && (event.getProperties()[0] instanceof UserField)) {
        UserField field = (UserField) event.getProperties()[0];
        Object instance = event.getObject();

        if (instance instanceof UserInstance) {
          if (((UserInstance) instance).getType().isAssignableTo(SScene.class)) {
            this.sceneInstance = (UserInstance) instance;
          }

          instance = ((UserInstance) instance).getJavaInstance();
        }

        this.instanceMap.put(instance, field);
      }
    }

    // Lambda invocations come from eventListeners and are
    // recorded outside the default record loop
    if (eventMsg == VMMessage.START_LAMBDA_INVOKE) {
      if (event.getObject() instanceof UserLambda) {
        startLambdaInvocation(event);
      } else {
        throw new ExecutionObserverException(event);
      }
    } else if (eventMsg == VMMessage.END_LAMBDA_INVOKE) {
      if (event.getObject() instanceof UserLambda) {
        endLambdaInvocation(event);
      } else {
        throw new ExecutionObserverException(event);
      }
    }

    // Should we record this message?
    boolean shouldRecord = isRecording();
    if (!shouldRecord) {
      if (event.getThread() != null) {
        shouldRecord = event.getThread().getDescription().contentEquals("eventThread");
      }
    }

    synchronized (this) {
      if (shouldRecord) {
        switch (eventMsg) {
          case RESET:
            reset();
            break;
          case START_INVOKE_ENTRY_POINT:
            this.hasInvokedEntryPoint = true;
            break;
          case START_EXP_EVAL:
            if (this.hasInvokedEntryPoint) {
              if (event.getObject() instanceof Expression) {

                // Non-function method invocations are handled separately
                if (event.getObject() instanceof MethodInvocation) {
                  MethodInvocation methodInvocation = (MethodInvocation) event.getObject();
                  if (methodInvocation.method.getValue().isFunction()) {
                    startExpressionEvaluation(event);
                  }
                } else {
                  startExpressionEvaluation(event);
                }
              } else {
                throw new ExecutionObserverException(event);
              }
            }
            break;
          case END_EXP_EVAL:
            if (this.hasInvokedEntryPoint) {
              if (event.getObject() instanceof Expression) {

                // Non-function method invocations are handled separately
                if (event.getObject() instanceof MethodInvocation) {
                  MethodInvocation methodInvocation = (MethodInvocation) event.getObject();
                  if (methodInvocation.method.getValue().isFunction()) {
                    endExpressionEvaluation(event);
                  }
                } else {
                  endExpressionEvaluation(event);
                }
              } else {
                throw new ExecutionObserverException(event);
              }
            }
            break;
          case START_METHOD_INVOKE:
            if (this.hasInvokedEntryPoint) {
              if (event.getObject() instanceof MethodInvocation) {
                startMethodInvocation(event);
              } else {
                throw new ExecutionObserverException(event);
              }
            }
            break;
          case START_STMT_EXEC:
            if (this.hasInvokedEntryPoint) {
              if (event.getObject() instanceof BlockStatement) {
                // pass
                //						} else if( event.getObject() instanceof Comment ) {
                //							//pass
                //						} else {
              } else {
                startStatement(event);
              }
            }
            break;
          case END_STMT_EXEC:
            if (this.hasInvokedEntryPoint) {
              if (event.getObject() instanceof BlockStatement) {
                //							//pass
                //						} else if( event.getObject() instanceof Comment ) {
                //							//pass
                //						} else {
              } else {
                endStatement(event);
              }
            }
            break;
          case START_CONTAINER:
            if (this.hasInvokedEntryPoint) {
              if ((event.getObject() instanceof AbstractStatementWithBody)
                  || (event.getObject() instanceof BlockStatement)) {
                startContainer(event);
              } else {
                throw new ExecutionObserverException(event);
              }
            }
            break;
          case END_CONTAINER:
            if (this.hasInvokedEntryPoint) {
              if ((event.getObject() instanceof AbstractStatementWithBody)
                  || (event.getObject() instanceof BlockStatement)) {
                endContainer(event);
              } else {
                throw new ExecutionObserverException(event);
              }
            }
            break;
        }
      }
    }
  }

  private void startLambdaInvocation(VMObservableEvent event) {
    org.lgna.project.ast.UserLambda lambda = (UserLambda) event.getObject();
    ComponentThread thread = event.getThread();
    double startTime = event.getTime();
    org.lgna.project.ast.AbstractMethod method = (AbstractMethod) event.getProperties()[0];

    // We ignore scene activation
    if (!method.getName().contentEquals("sceneActivated")) {
      AbstractEventNode<?> eventNode =
          EventNodeFactory.createEventNode(lambda, thread, startTime, null);
      ((LambdaEventNode) eventNode).setInvokingEventMethod(method);

      pushEventNode(eventNode, false);
    }
  }

  private void endLambdaInvocation(VMObservableEvent event) {
    org.lgna.project.ast.UserLambda lambda = (UserLambda) event.getObject();
    org.lgna.project.ast.AbstractMethod method = (AbstractMethod) event.getProperties()[0];
    ComponentThread thread = event.getThread();
    double endTime = event.getTime();

    if (!method.getName().contentEquals("sceneActivated")) {
      AbstractEventNode<?> eventNode = popEventNode(thread, false);

      lambdaEventNodes.add((LambdaEventNode) eventNode);

      if ((eventNode != null)
          && (eventNode.getAstNode() == lambda)
          && (eventNode.getThread() == thread)) {
        eventNode.setEndTime(endTime);
      } else {
        throw new ExecutionObserverException("EventNode invalid: " + eventNode.toString(), event);
      }
    }
  }

  /**
   * Handles the beginning of evaluation of an {@link Expression}.
   *
   * @param event VMObservableEvent event for expression
   */
  private void startExpressionEvaluation(VMObservableEvent event) {
    Expression expression = (Expression) event.getObject();
    ComponentThread thread = event.getThread();
    double startTime = event.getTime();

    AbstractEventNode<?> parentNode = peekEventNode(thread);

    ExpressionEvaluationEventNode eventNode =
        (ExpressionEvaluationEventNode)
            EventNodeFactory.createEventNode(expression, thread, startTime, parentNode);

    // Add expression evaluation to ExpressionStatementEventNode
    if (parentNode instanceof ExpressionStatementEventNode) {
      ((ExpressionStatementEventNode) parentNode).addExpressionEvaluationNode(eventNode);
    }
    // Handle expression evaluation for ConditionalEventNode
    else if (parentNode instanceof ConditionalStatementEventNode) {
      ((ConditionalStatementEventNode) parentNode).addConditionalEvaluation(eventNode);
    }
    // Handle expression evaluation for CountLoopEventNode
    else if (parentNode instanceof CountLoopEventNode) {
      ((CountLoopEventNode) parentNode).setCountExpressionNode(eventNode);
    }
    // Handle expression evaluation for EachInArrayTogetherEventNode
    else if (parentNode instanceof EachInArrayTogetherEventNode) {
      ((EachInArrayTogetherEventNode) parentNode).setArrayExpressionNode(eventNode);
    }
    // Handle expression evaluation for ForEachInArrayLoopEventNode
    else if (parentNode instanceof ForEachInArrayLoopEventNode) {
      ((ForEachInArrayLoopEventNode) parentNode).setArrayExpressionNode(eventNode);
    }
    // Handle expression evaluation for WhileLoopEventNode
    else if (parentNode instanceof WhileLoopEventNode) {
      ((WhileLoopEventNode) parentNode).addConditionalEvaluation(eventNode);
    }
    // Handle expression evaluation for LocalDeclarationStatementEventNode
    else if (parentNode instanceof LocalDeclarationStatementEventNode) {
      ((LocalDeclarationStatementEventNode) parentNode).setInitializerExpression(eventNode);
    }
    // Handle expression evaluation for ReturnStatementEventNode
    else if (parentNode instanceof ReturnStatementEventNode) {
      ((ReturnStatementEventNode) parentNode).setExpressionNode(eventNode);
    }
    // Handle expression evaluation for ExpressionEvaluationEventNode
    else if (parentNode instanceof ExpressionEvaluationEventNode) {
      // pass - handled on endExpressionEvaluation
    } else {
      throw new ExecutionObserverException("Parent node invalid:" + parentNode.toString(), event);
    }

    pushEventNode(eventNode, false);
  }

  /**
   * Handles the ending of evaluation of an {@link Expression}.
   *
   * @param event VMObservableEvent event for expression
   */
  private void endExpressionEvaluation(VMObservableEvent event) {
    Expression expression = (Expression) event.getObject();
    ComponentThread thread = event.getThread();
    double endTime = event.getTime();
    Object value = event.getProperties()[0];

    AbstractEventNode<?> eventNode = popEventNode(thread, false);

    if ((eventNode != null)
        && (eventNode.getAstNode() == expression)
        && (eventNode.getThread() == thread)) {
      eventNode.setEndTime(endTime);
      ((ExpressionEvaluationEventNode) eventNode).setValue(value);

      UserField field = this.getUserFieldForInstance(value);
      if (field != null) {
        ((ExpressionEvaluationEventNode) eventNode).setValueField(field);
      }
    } else {
      throw new ExecutionObserverException("EventNode invalid: " + eventNode.toString(), event);
    }
  }

  /**
   * Handles beginning execution of a {@link Statement}.
   *
   * @param event {@link VMObservableEvent} event for statement
   */
  private void startStatement(VMObservableEvent event) {
    Statement statement = (Statement) event.getObject();
    ComponentThread thread = event.getThread();
    double startTime = event.getTime();

    AbstractEventNode<?> parentNode = peekEventNode(getThreadForNode(statement, thread));

    // A Statement should always have a parent node (which can only be a ContainerEventNode)
    if (parentNode instanceof ContainerEventNode) {
      ContainerEventNode<?> containerNode = (ContainerEventNode<?>) parentNode;
      AbstractEventNode<?> eventNode =
          EventNodeFactory.createEventNode(statement, thread, startTime, containerNode);

      pushEventNode(eventNode, false);
    } else {
      throw new ExecutionObserverException("Parent node invalid: " + parentNode.toString(), event);
    }
  }

  /**
   * Handles ending execution of a {@link Statement}.
   *
   * @param event {@link VMObservableEvent} event for statement
   */
  private void endStatement(VMObservableEvent event) {
    Statement statement = (Statement) event.getObject();
    ComponentThread thread = event.getThread();
    double endTime = event.getTime();

    AbstractEventNode<?> eventNode = popEventNode(thread, true);

    if ((eventNode != null)
        && (eventNode.getAstNode() == statement)
        && (eventNode.getThread() == thread)) {
      eventNode.setEndTime(endTime);
    } else {
      throw new ExecutionObserverException("EventNode invalid: " + eventNode.toString(), event);
    }
  }

  /**
   * Handles beginning execution of container statement ( {@link AbstractStatementWithBody} or
   * {@link BlockStatement}).
   *
   * @param event {@link VMObservableEvent} event for container type statement
   */
  private void startContainer(VMObservableEvent event) {
    Statement statement = (Statement) event.getObject();
    ComponentThread thread = event.getThread();
    double startTime = event.getTime();

    AbstractEventNode<?> parentNode = peekEventNode(getThreadForNode(statement, thread));

    // Root case
    if (parentNode == null) {
      AbstractEventNode<?> eventNode =
          EventNodeFactory.createEventNode(statement, thread, startTime, null);
      this.rootEventNode = eventNode;
      pushEventNode(eventNode, true);
    } else if (parentNode instanceof ConditionalStatementEventNode) {
      AbstractEventNode<?> eventNode =
          EventNodeFactory.createEventNode(statement, thread, startTime, parentNode);
      pushEventNode(eventNode, true);
    } else if (parentNode instanceof ContainerEventNode) {
      AbstractEventNode<?> eventNode =
          EventNodeFactory.createEventNode(statement, thread, startTime, parentNode);
      pushEventNode(eventNode, true);
    } else if (parentNode instanceof ExpressionStatementEventNode) {
      AbstractEventNode<?> eventNode =
          EventNodeFactory.createEventNode(statement, thread, startTime, parentNode);
      ((ExpressionStatementEventNode) parentNode)
          .addUserMethodEventNode((ContainerEventNode<?>) eventNode);
      pushEventNode(eventNode, true);
    } else if (parentNode instanceof ExpressionEvaluationEventNode) {
      AbstractEventNode<?> eventNode =
          EventNodeFactory.createEventNode(statement, thread, startTime, parentNode);
      pushEventNode(eventNode, true);
    } else if (parentNode instanceof LambdaEventNode) {
      AbstractEventNode<?> eventNode =
          EventNodeFactory.createEventNode(statement, thread, startTime, parentNode);
      ((LambdaEventNode) parentNode).addBodyEventNode((ContainerEventNode<?>) eventNode);
      pushEventNode(eventNode, true);
    } else {
      throw new ExecutionObserverException("Parent node invalid: " + parentNode.toString(), event);
    }
  }

  /**
   * Handles ending execution of Container statement ( {@link AbstractStatementWithBody} or {@link
   * BlockStatement}).
   *
   * @param event {@link VMObservableEvent} event for container type statement
   */
  private void endContainer(VMObservableEvent event) {
    Statement statement = (Statement) event.getObject();
    ComponentThread thread = event.getThread();
    double endTime = event.getTime();

    AbstractEventNode<?> eventNode = popEventNode(thread, true);

    if ((eventNode != null)
        && (eventNode.getAstNode() == statement)
        && (eventNode.getThread() == thread)) {
      eventNode.setEndTime(endTime);
    } else {
      throw new ExecutionObserverException("EventNode invalid: " + eventNode.toString(), event);
    }
  }

  /**
   * Handles beginning execution of {@link MethodInvocation}.
   *
   * @param event {@link VMObservableEvent} event for invocation
   */
  private void startMethodInvocation(VMObservableEvent event) {
    MethodInvocation invocation = (MethodInvocation) event.getObject();
    ComponentThread thread = event.getThread();
    Object instance = event.getProperties()[1];

    UserField field = getUserFieldForInstance(instance);

    AbstractEventNode<?> parentNode = peekEventNode(getThreadForNode(invocation, thread));

    // Add instance and referencing field to parent node
    if (parentNode instanceof ExpressionStatementEventNode) {
      ExpressionStatementEventNode statementNode = (ExpressionStatementEventNode) parentNode;
      if ((instance != null) & (field != null)) {
        statementNode.setCallerInstance(instance);
        statementNode.setCallerField(field);
      }

      if ((instance != null) & (field != null)) {
        notifyListenersOfStart(statementNode); // Now that caller has been set, notify listeners
      }

      if (invocation.method.getValue() instanceof UserMethod) {
        UserMethod userMethod = (UserMethod) invocation.method.getValue();
        if (!userMethod.isFunction()) {
          statementNode.setUserMethod(userMethod);
        }
      }
    } else if (parentNode instanceof ExpressionEvaluationEventNode) {
      if (field != null) {
        ((ExpressionEvaluationEventNode) parentNode).setValueField(field);
      }
    }
  }

  /**
   * Clears all maps involved in tracking. Note: this method does <i>not</i> remove <code>
   * CurrentExecutionListeners</code>.
   */
  private void reset() {
    statementEventNodes.clear();
    eventNodeStack.clear();
  }

  /**
   * Pushes an {@link AbstractEventNode<?>} onto the stack and executes associated functions.
   *
   * @param eventNode <code>AbstractEventNode<?></code> to push onto the stack
   * @param shouldNotify boolean dictating whether listeners should be notified of push
   */
  private void pushEventNode(AbstractEventNode<?> eventNode, boolean shouldNotify) {
    ArrayList<AbstractEventNode<?>> eventNodes =
        this.statementEventNodes.get(eventNode.getAstNode());
    if (eventNodes == null) {
      eventNodes = new ArrayList<AbstractEventNode<?>>();
      if (eventNode.getAstNode() instanceof Statement) {
        this.statementEventNodes.put((Statement) eventNode.getAstNode(), eventNodes);
      }
    }
    eventNodes.add(eventNode);
    this.eventNodeStack.push(eventNode, eventNode.getThread());

    if (shouldNotify) {
      notifyListenersOfStart(eventNode);
    }
  }

  /**
   * Peeks {@link AbstractEventNode<?>} from top of stack for given thread.
   *
   * @param thread {@link ComponentThread} to check stack for
   * @return AbstractEventNode<?> on top of stack
   */
  private AbstractEventNode<?> peekEventNode(ComponentThread thread) {
    return this.eventNodeStack.peek(thread);
  }

  /**
   * Removes and returns {@link AbstractEventNode<?>} from top of stack for a given thread.
   *
   * @param thread {@link ComponentThread} to remove stack for
   * @return <code>AbstractEventNode<?></code> removed from stack
   */
  private AbstractEventNode<?> popEventNode(ComponentThread thread, boolean shouldNotify) {
    AbstractEventNode<?> rv = this.eventNodeStack.pop(thread);

    if (shouldNotify) {
      notifyListenersOfEnd(rv);
    }
    return rv;
  }

  /**
   * Gets the correct thread for lookup in {@link KeyedStack}. In the instance of parallel execution
   * (<code>DoTogether</code> and <code>EachInArrayTogether</code> statements) we want to get the
   * parent thread.
   *
   * @param astNode {@link Node} in AST to check
   * @param thread {@link ComponentThread} to reference
   * @return the correct <code>ComponentThread</code> for lookup
   */
  private ComponentThread getThreadForNode(Node astNode, ComponentThread thread) {
    if (astNode.getParent() instanceof BlockStatement) {
      BlockStatement blockStatement = (BlockStatement) astNode.getParent();
      if (blockStatement.getParent() instanceof DoTogether) {
        DoTogether doTogether = (DoTogether) blockStatement.getParent();

        // special case for DoTogether with only one statement
        if (doTogether.body.getValue().statements.size() > 1) {
          return thread.getParentThread();
        } else {
          return thread;
        }
      } else {
        return thread;
      }
    } else if (astNode.getParent() instanceof EachInArrayTogether) {
      return thread.getParentThread();
    } else {
      return thread;
    }
  }

  private void notifyListenersOfStart(AbstractEventNode<?> eventNode) {
    synchronized (this.executionListeners) {
      for (CurrentExecutionListener listener : this.executionListeners) {
        listener.startingExecution(eventNode);
      }
    }
  }

  private void notifyListenersOfEnd(AbstractEventNode<?> eventNode) {
    synchronized (this.executionListeners) {
      for (CurrentExecutionListener listener : this.executionListeners) {
        listener.endingExecution(eventNode);
      }
    }
  }

  /**
   * Based on provided <code>Object</code>, finds the applicable field set during instance creation.
   *
   * @param caller object evaluated by vm
   * @return mapped <code>UserField</code> for value
   */
  private UserField getUserFieldForInstance(Object instance) {
    if (instance instanceof UserInstance) {
      instance = ((UserInstance) instance).getJavaInstance();
    }
    // Get instance from invocation - special case for joints
    else if (instance instanceof org.lgna.story.SJoint) {
      org.lgna.story.SJoint joint = (org.lgna.story.SJoint) instance;

      org.lgna.story.implementation.JointImp jointImp =
          org.lgna.story.EmployeesOnly.getImplementation(joint);
      org.lgna.story.implementation.JointedModelImp<?, ?> jointedModelImp =
          jointImp.getJointedModelParent();
      org.lgna.story.SJointedModel jointedModel = jointedModelImp.getAbstraction();
      instance = jointedModel;
    }

    return this.instanceMap.get(instance);
  }

  /**
   * Specialized stack-like structure that allows for multiple stacks based on a key. Each key
   * passed into the <code>KeyedStack</code> is given a unique <code>Stack</code> and all
   * interactions with the <code>KeyedStack</code> require said key.
   *
   * @author Michael Pogran
   */
  private class KeyedStack<K, V> {
    private HashMap<K, java.util.Stack<V>> stackMap = Maps.newHashMap();

    public V push(V value, K key) {
      java.util.Stack<V> stack = this.stackMap.get(key);
      if (stack == null) {
        stack = new java.util.Stack<V>();
        this.stackMap.put(key, stack);
      }
      return stack.push(value);
    }

    public V peek(K key) {
      java.util.Stack<V> stack = this.stackMap.get(key);
      if (stack != null) {
        return stack.peek();
      } else {
        return null;
      }
    }

    public V pop(K key) {
      java.util.Stack<V> stack = this.stackMap.get(key);
      if (stack != null) {
        return stack.pop();
      } else {
        return null;
      }
    }

    public void clear() {
      stackMap = edu.cmu.cs.dennisc.java.util.Maps.newHashMap();
    }
  }
}
Beispiel #9
0
/** @author Dennis Cosgrove */
public class GlrScene extends GlrComposite<edu.cmu.cs.dennisc.scenegraph.Scene> {
  @Override
  public void initialize(edu.cmu.cs.dennisc.scenegraph.Scene sgElement) {
    super.initialize(sgElement);
    for (edu.cmu.cs.dennisc.scenegraph.Component sgComponent :
        edu.cmu.cs.dennisc.pattern.VisitUtilities.getAll(
            owner, edu.cmu.cs.dennisc.scenegraph.Component.class)) {
      GlrComponent<?> glrComponent = AdapterFactory.getAdapterFor(sgComponent);
      this.addDescendant(glrComponent);
    }
  }

  public GlrBackground getBackgroundAdapter() {
    return this.backgroundAdapter;
  }

  protected void addDescendant(GlrComponent<?> glrDescendant) {
    if (glrDescendant instanceof GlrGhost) {
      synchronized (this.glrGhostDescendants) {
        this.glrGhostDescendants.add((GlrGhost) glrDescendant);
      }
    } else if (glrDescendant instanceof GlrVisual<?>) {
      synchronized (this.glrVisualDescendants) {
        this.glrVisualDescendants.add((GlrVisual<?>) glrDescendant);
      }
      if (glrDescendant instanceof GlrPlanarReflector) {
        synchronized (this.glrPlanarReflectorDescendants) {
          this.glrPlanarReflectorDescendants.add((GlrPlanarReflector) glrDescendant);
        }
      }
    }
  }

  protected void removeDescendant(GlrComponent<?> glrDescendant) {
    if (glrDescendant instanceof GlrGhost) {
      synchronized (this.glrGhostDescendants) {
        this.glrGhostDescendants.remove(glrDescendant);
      }
    } else if (glrDescendant instanceof GlrVisual<?>) {
      synchronized (this.glrVisualDescendants) {
        this.glrVisualDescendants.remove(glrDescendant);
      }
      if (glrDescendant instanceof GlrPlanarReflector) {
        synchronized (this.glrPlanarReflectorDescendants) {
          this.glrPlanarReflectorDescendants.remove(glrDescendant);
        }
      }
    }
  }

  @Deprecated
  public void EPIC_HACK_FOR_THUMBNAIL_MAKER_removeDescendant(GlrComponent<?> glrDescendant) {
    this.removeDescendant(glrDescendant);
  }

  public void renderAlphaBlended(RenderContext rc) {
    // todo depth sort
    // rc.gl.glDisable( GL_DEPTH_TEST );
    //		rc.gl.glDepthMask( false );
    //		try {
    synchronized (this.glrGhostDescendants) {
      for (GlrGhost ghostAdapter : this.glrGhostDescendants) {
        ghostAdapter.renderGhost(rc, ghostAdapter);
      }
    }
    synchronized (this.glrVisualDescendants) {
      for (GlrVisual<? extends edu.cmu.cs.dennisc.scenegraph.Visual> visualAdapter :
          this.glrVisualDescendants) {
        if (visualAdapter.isAlphaBlended()) {
          // todo: adapters should be removed
          if ((visualAdapter.owner != null)
              && (visualAdapter.owner.getRoot() instanceof edu.cmu.cs.dennisc.scenegraph.Scene)) {
            if (visualAdapter.isAllAlpha()) {
              visualAdapter.renderAllAlphaBlended(rc);
            } else {
              visualAdapter.renderAlphaBlended(rc);
            }
          }
        }
      }
    }
    //		} finally {
    //			rc.gl.glDepthMask( true );
    //		}
    // rc.gl.glEnable( GL_DEPTH_TEST );
  }

  @Override
  public void setupAffectors(RenderContext rc) {
    rc.setGlobalBrightness(this.globalBrightness);
    rc.beginAffectorSetup();
    super.setupAffectors(rc);
    rc.endAffectorSetup();
  }

  private void renderScene(RenderContext rc) {
    rc.gl.glDisable(GL_BLEND);
    renderOpaque(rc);
    rc.gl.glEnable(GL_BLEND);
    rc.gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    renderAlphaBlended(rc);
    rc.gl.glDisable(GL_BLEND);
  }

  public void renderScene(
      RenderContext rc,
      GlrAbstractCamera<? extends edu.cmu.cs.dennisc.scenegraph.AbstractCamera> cameraAdapter,
      GlrBackground backgroundAdapter) {
    rc.gl.glMatrixMode(GL_MODELVIEW);
    synchronized (cameraAdapter) {
      rc.gl.glLoadMatrixd(cameraAdapter.accessInverseAbsoluteTransformationAsBuffer());
    }

    if (backgroundAdapter != null) {
      // pass
    } else {
      backgroundAdapter = this.backgroundAdapter;
    }
    if (backgroundAdapter != null) {
      backgroundAdapter.setup(rc);
    }

    if (this.glrPlanarReflectorDescendants.size() > 0) {
      GlrPlanarReflector planarReflectorAdapter = this.glrPlanarReflectorDescendants.get(0);
      if (planarReflectorAdapter.isFacing(cameraAdapter)) {
        rc.gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        rc.gl.glColorMask(false, false, false, false);
        rc.gl.glEnable(GL_STENCIL_TEST);
        rc.gl.glStencilFunc(GL_ALWAYS, 1, 1);
        rc.gl.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
        rc.gl.glDisable(GL_DEPTH_TEST);
        planarReflectorAdapter.renderStencil(rc, GlrVisual.RenderType.OPAQUE);
        rc.gl.glEnable(GL_DEPTH_TEST);
        rc.gl.glColorMask(true, true, true, true);
        rc.gl.glStencilFunc(GL_EQUAL, 1, 1);
        rc.gl.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        rc.gl.glEnable(GL_CLIP_PLANE0);
        rc.gl.glPushMatrix();
        planarReflectorAdapter.applyReflection(rc);
        rc.gl.glFrontFace(GL_CW);
        setupAffectors(rc);
        renderScene(rc);
        rc.gl.glFrontFace(GL_CCW);
        rc.gl.glPopMatrix();
        rc.gl.glDisable(GL_CLIP_PLANE0);
        rc.gl.glDisable(GL_STENCIL_TEST);
        setupAffectors(rc);
        rc.gl.glEnable(GL_BLEND);
        rc.gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        planarReflectorAdapter.renderStencil(rc, GlrVisual.RenderType.ALPHA_BLENDED);
        rc.gl.glDisable(GL_BLEND);
      } else {
        rc.gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        setupAffectors(rc);
      }
    } else {
      rc.gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      setupAffectors(rc);
    }
    renderScene(rc);
  }

  @Override
  protected void propertyChanged(edu.cmu.cs.dennisc.property.InstanceProperty<?> property) {
    if (property == owner.background) {
      this.backgroundAdapter = AdapterFactory.getAdapterFor(owner.background.getValue());
    } else if (property == owner.globalBrightness) {
      this.globalBrightness = owner.globalBrightness.getValue();
    } else {
      super.propertyChanged(property);
    }
  }

  private GlrBackground backgroundAdapter;
  private float globalBrightness;
  private final java.util.List<GlrGhost> glrGhostDescendants =
      edu.cmu.cs.dennisc.java.util.Lists.newLinkedList();
  private final java.util.List<GlrVisual<?>> glrVisualDescendants =
      edu.cmu.cs.dennisc.java.util.Lists.newLinkedList();
  private final java.util.List<GlrPlanarReflector> glrPlanarReflectorDescendants =
      edu.cmu.cs.dennisc.java.util.Lists.newLinkedList();
}