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(); } } }
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); } } }