예제 #1
0
MM::VOID MM::PoolNodeBehavior::sub(MM::Instance * i,
                                   MM::Machine  * m,
                                   MM::Node     * n,
                                   MM::UINT32     amount)
{
  //in case of instance pool: delete instances
  if(of != MM_NULL)
  {
    MM::Definition * def = i->getDefinition();
    MM::Element * unitDef = def->findDeclaredDefinition(of);
    if(unitDef != MM_NULL &&
       unitDef->instanceof(MM::T_Definition) == MM_TRUE)
    {
      i->destroyInstances(n, m, amount);
    }
  }
    
  //subtract from old value
  MM::INT32 oldValue = i->getOldValue(n);
  oldValue = oldValue - amount;
  i->setOldValue(n, oldValue);
  
  //subtract from new value
  MM::INT32 newValue = i->getNewValue(n);
  newValue = newValue - amount;
  i->setNewValue(n, newValue);

  //check if self is empty, which kills this instance
  if(newValue == 0)
  {
    MM::Name * poolName = n->getName();
    if(poolName->equals((MM::CHAR*)MM::PoolNodeBehavior::SELF_STR,
                      MM::PoolNodeBehavior::SELF_LEN) == MM_TRUE)
    {
      //inform parent instance of the demise of instance
      //MM::Instance * parentInstance = i->getParent();
      //parentInstance->destroyInstance(n, m, i);

      //set the new value of the pool node instance one lower
      MM::Element * decl = i->getDeclaration();
      if(decl->instanceof(MM::T_Node) == MM_TRUE)
      {
        MM::Node * declNode = (MM::Node *) decl;
        //must be a pool node!
        MM::Instance * parent = i->getParent();
        MM::INT32 val = parent->getNewValue(declNode);
        parent->setNewValue(declNode, val-100);
        //NOTE: can't use setDirty because sweeep happens after finalize
        //manually notify sub and has value
        parent->notifyObservers(parent, (MM::VOID*) 100, MM::MSG_SUB_VALUE, declNode);
        parent->notifyObservers(parent, (MM::VOID*)(val-100), MM::MSG_HAS_VALUE, declNode);			 
      }

      i->mark();
    }
  }
}
예제 #2
0
MM::VOID MM::Evaluator::notifyFlow(MM::Transition * tr)
{
  MM::Vector<MM::Element *> * elements = tr->getElements();
  MM::Vector<MM::Element *>::Iterator eIter = elements->getIterator();
  MM::Element * element;
  
  while(eIter.hasNext() == MM_TRUE)
  {
    element = eIter.getNext();
    /*TODO: improve this --> */
    if(element->instanceof(MM::T_FlowEvent) == MM_TRUE)
    {
      MM::FlowEvent * event = (MM::FlowEvent *) element;
      
	    MM::Instance * instance = event->getInstance();
      MM::Instance * srcInstance = event->getSourceInstance();
      MM::Instance * tgtInstance = event->getTargetInstance();
      MM::Node * srcNode = event->getSourceNode();
      MM::Node * tgtNode = event->getTargetNode();
      MM::UINT32 amount = event->getAmount();
      
	    srcInstance->notifyObservers(srcInstance, (MM::VOID*)amount, MM::MSG_SUB_VALUE, srcNode);
      tgtInstance->notifyObservers(tgtInstance, (MM::VOID*)amount, MM::MSG_ADD_VALUE, tgtNode);

      //hack to notify the instance in which the flow occurred
	    if(srcInstance != tgtInstance)
	    {
		    srcInstance->notifyObservers(srcInstance, (MM::VOID*)amount, MM::MSG_ADD_VALUE, tgtNode);
	      tgtInstance->notifyObservers(tgtInstance, (MM::VOID*)amount, MM::MSG_SUB_VALUE, srcNode);
		  }

	    //let observers of instances know the current value of a pool.
      /*
      if(srcNode->getBehavior()->instanceof(MM::T_PoolNodeBehavior) == MM_TRUE)
      {
        MM::INT32 srcAmount = srcNode->getAmount(srcInstance, m);
        srcInstance->notifyObservers(srcInstance, (MM::VOID*)srcAmount, MM::MSG_HAS_VALUE, srcNode);
      }
      if(tgtNode->getBehavior()->instanceof(MM::T_PoolNodeBehavior) == MM_TRUE)
      {
        MM::INT32 tgtAmount = tgtNode->getAmount(tgtInstance, m);
        tgtInstance->notifyObservers(tgtInstance, (MM::VOID*)tgtAmount, MM::MSG_HAS_VALUE, tgtNode);
      }
      */
    }
	  else if(element->instanceof(MM::T_Event) == MM_TRUE)
	  {
      MM::Event * event = (MM::Event *) element;
      MM::Element * e = event->getElement();
      MM::Instance * i = event->getInstance();
      MM::MESSAGE msg = event->getMessage();
      i->notifyObservers(i, (MM::VOID*)0, msg, e); 
	  }
  }
}