public ActionNode getActionByNameFor(AID agent, string action) { //assuming only one action exists by that name ! List <ActionNode> allActionNodes = getAllActions(); ActionNode found = null; for (int i = 0; i < allActionNodes.Count; ++i) { //agentToPartition.getMap(agent.toString()).name; if ((allActionNodes[i].Partitions[0].name == agentToPartition[agent.toString()].name) && (action == clean(allActionNodes[i].name))) { found = allActionNodes[i]; break; } } return(found); }
public List <ActionNode> getAllActions() { List <ActivityNode> allNodes = procedure.Activity.Nodes; List <ActionNode> actionNodes = new List <ActionNode>(); for (int i = 0; i < allNodes.Count; ++i) { if (allNodes[i].Kind == "LoopNode") { continue; } if (allNodes[i].Kind == "action") { ActionNode aNode = (ActionNode)(allNodes[i]); actionNodes.Add(aNode); continue; } } return(actionNodes); }
//FinalNode, Merge et Decision devraent �tre des activityNode !! public void addActivityNode(XElement node, Activity activity) { MascaretApplication.Instance.VRComponentFactory.Log("New activity node"); string type = ""; string id = ""; if (node.Attribute("{http://schema.omg.org/spec/XMI/2.1}type") != null) type = node.Attribute("{http://schema.omg.org/spec/XMI/2.1}type").Value; else type = node.Attribute("{http://www.omg.org/spec/XMI/20131001}type").Value; MascaretApplication.Instance.VRComponentFactory.Log(" Type : " + type); if (node.Attribute("{http://schema.omg.org/spec/XMI/2.1}id") != null) id = node.Attribute("{http://schema.omg.org/spec/XMI/2.1}id").Value; else id = node.Attribute("{http://www.omg.org/spec/XMI/20131001}id").Value; MascaretApplication.Instance.VRComponentFactory.Log(" ID : " + id); string name = ""; if (node.Attribute("name") != null) name = node.Attribute("name").Value; else name = id; MascaretApplication.Instance.VRComponentFactory.Log(" Name : " + name); string idPartition = ""; if (node.Attribute("inPartition") != null) idPartition = node.Attribute("inPartition").Value; MascaretApplication.Instance.VRComponentFactory.Log(id); MascaretApplication.Instance.VRComponentFactory.Log(type); MascaretApplication.Instance.VRComponentFactory.Log(name); MascaretApplication.Instance.VRComponentFactory.Log(idPartition); ActivityNode actNode = null; //Debug.Log(" TYPE NODE : " + type); if (type == "uml:InitialNode") { actNode = new InitialNode(); activity.Initial = actNode; actNode.name = "Initial"; } else if (type == "uml:FinalNode" || type == "uml:ActivityFinalNode") { actNode = new FinalNode(); } else if (type == "uml:LoopNode") { addActivityGroup(node, activity); } else if (type == "uml:ForkNode") { actNode = new ForkNode(); } else if (type == "uml:JoinNode") { actNode = new JoinNode(); } else if (type == "uml:MergeNode") { actNode = new MergeNode(); } /*else if (type == "uml:DecisionNode") { actNode = new DecisionNode(); }*/ else if (type == "uml:ObjectNode" || type == "uml:CentralBufferNode") { ObjectNode objNode = new ObjectNode(name); Classifier ressourceType = getObjectNodeType(node); if (ressourceType != null) objNode.ResourceType = ressourceType; actNode = objNode; string type2 = node.Attribute("{http://schema.omg.org/spec/XMI/2.1}type").Value; if (_idClass.ContainsKey(type2)) ((ObjectNode)actNode).ResourceType = _idClass[type2]; } else if (type == "uml:ValueSpecificationAction") { /* shared_ptr<XmlNode> valueNode = node->getChildByName("value"); string expressionValue = valueNode->getProperty("value"); shared_ptr<Expression> expression = make_shared<Expression>(expressionValue, _model->getBasicType("boolean")); _activityExpressions[node->getProperty("id")] = expression; */ } else if (type == "uml:OpaqueAction") { if (isStereotypedPlayAnimation(node)) { string animationName = getAnimName(node); MascaretApplication.Instance.VRComponentFactory.Log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% NEW PLAY ANIMATION : " + name + " " + animationName); ActionNode an = new ActionNode(name, "action"); PlayAnimationAction ap = new PlayAnimationAction(); ap.Description = getComment(node); ap.name = name; ap.Owner = activity; ap.animationName = animationName; an.Action = ap; addPins(an, node); actNode = an; } } else if (type == "uml:CallBehaviorAction") { ActionNode an = new ActionNode(name, "action"); CallBehaviorAction cb = new CallBehaviorAction(); cb.Description = getComment(node); cb.name = name; cb.Owner = activity; XElement beNode = node.Element("behavior"); string opid; if (beNode != null) opid = beNode.Attribute("idref").Value; else opid = node.Attribute("behavior").Value; if (_idBehaviors.ContainsKey(opid)) { cb.Behavior = _idBehaviors[opid]; } else { // Debug.Log("[ModelLoader2 Info] Behavior " + opid // + " not yet found for ActionNode " + name + ". Postbone..."); _callBehaviors.Add(cb, opid); } an.Action = cb; addPins(an, node); actNode = an; } else if (type == "uml:CallOperationAction") { ActionNode an = new ActionNode(name, "action"); //Debug.Log("Action Node : " +name); CallOperationAction act = new CallOperationAction(); act.Description = getComment(node); an.Fml = getFML(node); act.name = name; act.Owner = activity; XElement opNode = node.Element("operation"); if (opNode != null) { string opid; opid = opNode.Attribute("idref").Value; //MascaretApplication.Instance.logfile.WriteLine("Operation ID : " + opid); MascaretApplication.Instance.logfile.Flush(); string stereo = getStereotype(opid); MascaretApplication.Instance.VRComponentFactory.Log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + name + " : " + opid + " " + stereo); if (stereo != "") { an.Stereotype = stereo; } if (_idOperations.ContainsKey(opid)) act.Operation = _idOperations[opid]; else { //cerr << "ERREUR PAS OPERATION... " << opid<< endl; _callOperations.Add(act, opid); } } else { string opid; opid = node.Attribute("operation").Value; // MascaretApplication.Instance.logfile.WriteLine("Operation ID : " + opid); MascaretApplication.Instance.logfile.Flush(); string stereo = getStereotype(opid); MascaretApplication.Instance.VRComponentFactory.Log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + name + " : " + opid + " " + stereo); if (stereo != "") { an.Stereotype = stereo; } // MascaretApplication.Instance.logfile.WriteLine("Operation ID : " + opid); MascaretApplication.Instance.logfile.Flush(); if (_idOperations.ContainsKey(opid)) { act.Operation = _idOperations[opid]; // MascaretApplication.Instance.logfile.WriteLine("Operation Name : " + act.Operation); MascaretApplication.Instance.logfile.Flush(); } else _callOperations.Add(act, opid); } an.Action = act; addPins(an, node); actNode = an; } else if (type == "uml:SendSignalAction") { MascaretApplication.Instance.VRComponentFactory.Log("SendSignalAction"); ActionNode an = new ActionNode(name, "action"); SendSignalAction act = new SendSignalAction(); XElement sigNode = node.Element("signal"); if (sigNode != null) { string signame = sigNode.Attribute("name").Value; if (!_signals.ContainsKey(signame)) { Signal ns = new Signal(signame); _signals.Add(signame, ns); } act.SignalClass = _signals[signame]; } else { string signame = ""; if (node.Attribute("signal") != null) signame = node.Attribute("signal").Value; if (!_signals.ContainsKey(signame)) { Signal ns = new Signal(signame); _signals.Add(signame, ns); } act.SignalClass = _signals[signame]; } XElement targetNode = node.Element("argument"); if (targetNode != null) { string targetName = targetNode.Attribute("name").Value; XElement typeNode = targetNode.Element("type"); string classid = ""; if (typeNode != null) classid = typeNode.Attribute("idref").Value; else classid = targetNode.Attribute("type").Value; act.Target = new SendSignalTarget(); act.Target.targetName = targetName; act.Target.targetClass = _idClass[classid]; } else { targetNode = node.Element("target"); if (targetNode != null) { MascaretApplication.Instance.VRComponentFactory.Log("SendSignal Target"); string targetName = targetNode.Attribute("name").Value; string classid = targetNode.Attribute("type").Value; MascaretApplication.Instance.VRComponentFactory.Log("name : " + targetName); MascaretApplication.Instance.VRComponentFactory.Log("name : " + targetName + " : " + _idClass[classid]); act.Target = new SendSignalTarget(); act.Target.targetName = targetName; act.Target.targetClass = _idClass[classid]; } else MascaretApplication.Instance.VRComponentFactory.Log("No target"); } an.Action = act; addPins(an, node); actNode = an; } else if (type == "uml:AddStructuralFeatureValueAction") { //cerr << " ############# Found a AddStructuralFeatureValueAction : " << endl; /* shared_ptr<ActionNode> an = make_shared<ActionNode>(name); shared_ptr<Classifier> type; shared_ptr<XmlNode> pinNode = node->getChildByName("object"); string attrName = pinNode->getProperty("name"); cerr << " Name == " << attrName << endl; shared_ptr<XmlNode> typeNode = pinNode->getChildByName("type"); if (typeNode && typeNode->getProperty("type") == "uml:PrimitiveType") { string href = typeNode->getProperty("href"); string strType = href.substr(href.rfind('#') + 1); boost::to_lower(strType); type = _model->getBasicType(strType); } shared_ptr<XmlNode> valueNode = pinNode->getChildByName("value"); if (valueNode) { string value = valueNode->getProperty("value"); cerr << " VALUE : " << value << endl; shared_ptr<Expression> expression = make_shared<Expression>(value, type); shared_ptr<AddStructuralFeatureValueAction> act = make_shared<AddStructuralFeatureValueAction>(); act->setValue(expression); act->setProperty(attrName); an->setAction(act); } actNode = an; */ } else if (type == "uml:AcceptEventAction") { MascaretApplication.Instance.VRComponentFactory.Log("New uml:AcceptEventAction"); ActionNode an = new ActionNode(name, "action"); AcceptEventAction act = new AcceptEventAction(); XElement triggerNode = node.Element("trigger"); if (triggerNode != null) { MascaretApplication.Instance.VRComponentFactory.Log("trigger node found"); Trigger trigger = new Trigger(name); MascaretApplication.Instance.VRComponentFactory.Log("Debug : " + name); string idT = ""; if (triggerNode.Attribute("{http://schema.omg.org/spec/XMI/2.1}id") != null) idT = triggerNode.Attribute("{http://schema.omg.org/spec/XMI/2.1}id").Value; else idT = triggerNode.Attribute("{http://www.omg.org/spec/XMI/20131001}id").Value; trigger.Id = idT; MascaretApplication.Instance.VRComponentFactory.Log(trigger.Id); if (triggerNode.Attribute("event") != null) { string idEvent = triggerNode.Attribute("event").Value; if (_events.ContainsKey(idEvent)) { trigger.MEvent = _events[idEvent]; act.setTrigger(trigger); } else MascaretApplication.Instance.VRComponentFactory.Log("Could not find event : " + idEvent); } } an.Action = act; addPins(an, node); actNode = an; MascaretApplication.Instance.VRComponentFactory.Log(" Fin AcceptEventAction"); } // ... else { //Debug.Log("Unknown state: " + type); } if (actNode != null) { _activityNodes.Add(id, actNode); activity.addNode(actNode); //cerr << "searching _partitions for '" << idPartition << "'" << endl; if (_partitions.ContainsKey(idPartition)) { actNode.Partitions.Add(_partitions[idPartition]); _partitions[idPartition].Node.Add(actNode); } actNode.Summary = getSummary(node); actNode.Description = getComment(node); actNode.Tags = getTags(node); } }
public void addPins(ActionNode an, XElement node) { foreach (XElement pins in node.Elements()) { if (pins.Name.LocalName == "argument") { MascaretApplication.Instance.VRComponentFactory.Log("ARGUMENT PIN ################################"); XAttribute att = pins.Attribute("{http://www.omg.org/spec/XMI/20131001}type"); if (att == null) att = pins.Attribute("{http://schema.omg.org/spec/XMI/2.1}type"); if (att != null) MascaretApplication.Instance.VRComponentFactory.Log(att.Value); if (att != null && att.Value == "uml:ValuePin") { ValuePin valuePin = new ValuePin(); XAttribute attID = pins.Attribute("{http://schema.omg.org/spec/XMI/2.1}id"); if (attID == null) attID = pins.Attribute("{http://www.omg.org/spec/XMI/20131001}id"); string id = attID.Value; string name = pins.Attribute("name").Value; MascaretApplication.Instance.VRComponentFactory.Log("Pin Name : " + name); valuePin.Id = id; valuePin.name = name; string strType = ""; XElement typeNode = pins.Element("type"); if (typeNode == null) { // Check if it's an attribute string typeId = pins.Attribute("type").Value; if (_primitiveTypes.ContainsKey(typeId)) strType = _primitiveTypes[typeId]; } else { XAttribute attr = (XAttribute)typeNode.Attribute("href"); if (attr != null) strType = attr.Value.Substring(attr.Value.IndexOf("#") + 1); } MascaretPrimitiveType attributeType = model.getBasicType(strType.ToLower()); valuePin.ResourceType = attributeType; string strValue = ""; XElement valueNode = pins.Element("value"); XAttribute attrV = (XAttribute)valueNode.Attribute("value"); if (attrV != null) strValue = attrV.Value; MascaretApplication.Instance.VRComponentFactory.Log("Valeur : " + strValue); valuePin.ValueSpec = attributeType.createValueFromString(strValue); /*Classifier ressourceType = getObjectNodeType(pins); if(ressourceType != null) valuePin.ResourceType = ressourceType;*/ an.Action.ValuePins.Add(valuePin); _objectNodes.Add(valuePin.Id, valuePin); } else { InputPin inputPin = new InputPin(); inputPin.Id = pins.Attribute("{http://schema.omg.org/spec/XMI/2.1}id").Value; if (inputPin.Id == null) inputPin.Id = pins.Attribute("{http://www.omg.org/spec/XMI/20131001}id").Value; inputPin.name = pins.Attribute("name").Value; Classifier ressourceType = getObjectNodeType(pins); if (ressourceType != null) inputPin.ResourceType = ressourceType; //Debug.Log(" AN : " + an); an.Action.InputPins.Add(inputPin); _objectNodes.Add(inputPin.Id, inputPin); } } else if (pins.Name.LocalName == "result") { OutputPin outputPin = new OutputPin(); outputPin.Id = pins.Attribute("id").Value; outputPin.name = pins.Attribute("name").Value; Classifier ressourceType = getObjectNodeType(pins); if (ressourceType != null) outputPin.ResourceType = ressourceType; an.Action.OutputPins.Add(outputPin); _objectNodes.Add(outputPin.Id, outputPin); } } }
bool IsBehaviourFinished(ActionNode node) { bool result = true; Dictionary<string, Agent> agents = MascaretApplication.Instance.AgentPlateform.Agents; foreach (KeyValuePair<string, Agent> agt in agents) { AgentBehaviorExecution pbehavior = agt.Value.getBehaviorExecutingByName("ProceduralBehavior"); // MascaretApplication.Instance.VRComponentFactory.Log ("++++++++++++++++++++++++checking ++++++++++" +node.name); if (pbehavior != null) { ProceduralBehavior procBehave = (ProceduralBehavior)(pbehavior); foreach (ProcedureExecution pe in procBehave.runningProcedures) { //MascaretApplication.Instance.VRComponentFactory.Log ("+++++++++++++++++++++++++Running++++++++++" +pe.procedure.name + " : " + pe.isFinished()); if (pe.procedure.name == node.Action.name) result = pe.isFinished(); if (!result) break; } } if (!result) break; } return result; }
void CallProceduralBehaviourExecution(ActionNode action) { MascaretApplication.Instance.VRComponentFactory.Log(Host.name + "+++++++++++++++++++++++++++########################################### CallProceduralBehaviourExecution " + action.name); MascaretApplication appli = MascaretApplication.Instance; //bool found = false; OrganisationalEntity askedOrg = null; Procedure askedProc = null; Role askedRole = null; List<OrganisationalEntity> orgs = appli.AgentPlateform.Organisations; appli.VRComponentFactory.Log("ProceduralBehaviourExecution"); for (int iOrg = 0; iOrg < orgs.Count; iOrg++) { appli.VRComponentFactory.Log("------ Org " + orgs[iOrg].name + " ?"); if (orgs[iOrg].name == parameters["orgEntity"].getStringFromValue()) { appli.VRComponentFactory.Log("----------Org : " + orgs[iOrg].name + " found"); OrganisationalStructure os = orgs[iOrg].Structure; List<Procedure> procs = os.Procedures; askedOrg = orgs[iOrg]; for (int iP = 0; iP < procs.Count; iP++) { if (procs[iP].name == action.Action.name) { appli.VRComponentFactory.Log("Procedure " + procs[iP].name + " found"); askedProc = procs[iP]; List<RoleAssignement> assigns = orgs[iOrg].RoleAssignement; appli.VRComponentFactory.Log("Assigns : " + assigns.Count); for (int iAss = 0; iAss < assigns.Count; iAss++) { agt = appli.AgentPlateform.Agents[assigns[iAss].Agent.toString()]; askedRole = assigns[iAss].Role; if (agt.name == Host.name) { appli.VRComponentFactory.Log("Role : " + assigns[iAss].Role.name + " == " + agt.name); AgentBehaviorExecution pbehavior = agt.getBehaviorExecutingByName("ProceduralBehavior"); if (pbehavior != null) { appli.VRComponentFactory.Log("Procedure " + askedProc.name + " launched for " + agt.name); ProceduralBehavior procBehave = (ProceduralBehavior)(pbehavior); Dictionary<string, ValueSpecification> procParams = new Dictionary<string, ValueSpecification>(); procBehave.pushProcedureToDo(askedProc, askedOrg, askedRole, procParams); } } } } } } } }
void CallGlobalActivityBehaviourExecution(ActionNode action) { MascaretApplication.Instance.VRComponentFactory.Log(Host.name + "+++++++++++++++++++++++++++########################################### CallGlobalActivityBehaviourExecution " + action.name); string orgEntity = null; List<OrganisationalStructure> structs = VRApplication.Instance.AgentPlateform.Structures; foreach (OrganisationalStructure s in structs) { List<Procedure> procs = s.Procedures; foreach (Procedure p in procs) { if (p.name == action.Action.name) { orgEntity = s.Entities[0].name; } } } List<Entity> entities = MascaretApplication.Instance.getEnvironment().getEntities(); Entity entity = entities[0]; Action action2 = null; /* action2 = new CallProcedureAction(); ((CallProcedureAction)(action2)).Procedure = procedure; ((CallProcedureAction)(action2)).OrganisationalEntity = orgEntity; BehaviorScheduler.Instance.executeBehavior(action2, entity, new Dictionary<string, ValueSpecification>(), false); */ action2 = new CallGlobalActivityAction(); ((CallGlobalActivityAction)(action2)).Procedure = action.Action.name; ((CallGlobalActivityAction)(action2)).OrganisationalEntity = orgEntity; BehaviorExecution be = BehaviorScheduler.Instance.executeBehavior(action2, entity, new Dictionary<string, ValueSpecification>(), false); behaviorToNode.Add(be, action); }
public ProcedureExecution(Procedure procedure, OrganisationalEntity organisation, Agent agent) { this.procedure = procedure; this.organisation = organisation; this.agent = agent; agentToPartition = new Dictionary <string, ActivityPartition>(); partitionToAgent = new Dictionary <ActivityPartition, AID>(); activeTokens = new List <ActivityExecutionToken>(); affectations = new Dictionary <string, InstanceSpecification>(); activityParams = new Dictionary <string, ValueSpecification>(); actionsRunning = new List <KeyValuePair <string, ActionNode> >(); actionsDone = new List <ActionNode>(); allActionsDone = new Dictionary <string, List <ActionNode> >(); // key: AID allActionsDoneTimestamps = new Dictionary <string, List <TimeExpression> >(); for (int i = 0; i < procedure.Activity.Partitions.Count; i++) { ActivityPartition partition = procedure.Activity.Partitions[i]; List <RoleAssignement> assignements = organisation.RoleAssignement; for (int j = 0; j < assignements.Count; j++) { if (partition.name == assignements[j].Role.name) { agentToPartition.Add(assignements[j].Agent.toString(), partition); partitionToAgent.Add(partition, assignements[j].Agent); Agent agt = MascaretApplication.Instance.AgentPlateform.Agents[assignements[j].Agent.toString()]; if (agt == null) { MascaretApplication.Instance.VRComponentFactory.Log("CA VA TRANCHER"); } affectations.Add(partition.name, agt); } } } ActivityExecutionToken initialToken = new ActivityExecutionToken(); initialToken.currentLocation = procedure.Activity.Initial; if (initialToken.currentLocation == null) { System.Console.WriteLine("ERROR: no initial node found, not allowed"); System.Console.WriteLine("Procedure will not start."); return; } List <ActivityEdge> controlFlows = procedure.Activity.Initial.getOutgoingControlFlowEdges(); if (controlFlows.Count == 1) { initialToken.outgoingEdge = controlFlows[0]; activeTokens.Add(initialToken); ActionNode dummyActionVariable = null; tryToAdvanceToken(initialToken, dummyActionVariable, true); //first advancement } else { if (controlFlows.Count == 0) { System.Console.WriteLine("WARNING: initial node has no outgoing edges"); } else { System.Console.WriteLine("ERROR: multiple outgoing edges for the initial node, not allowed"); } System.Console.WriteLine("Procedure will not start."); } }
protected bool actionIsCurrentlyRunning(ActionNode action) { //remove already running nodes :: TODO : check if we should allow this or not.... for (int i = 0; i < actionsRunning.Count; ++i) { if (actionsRunning[i].Value == action) { return true; } } return false; }
public void onActionDone(AID agent, ActionNode action) { for (int iP = 0; iP < runningProcedures.Count; iP++) { ProcedureExecution procInfo = runningProcedures[iP]; procInfo.informActionDone(agent, action); } ispause = false; }
protected bool tryToAdvanceToken(ActivityExecutionToken token, ActionNode doneAction, bool gotTicketToUseAction) { //TODO : current implementation will fail if the loop node has branches which are not joined together at the end //TODO : setup part of loop nodes not implemented //TODO : careful if the loop node contains only an initial node :: ENDLESS LOOP // Debug.Log(" current token : " + token.currentLocation.name); if (token.currentLocation.Kind == "action") { ActionNode aNode = (ActionNode)(token.currentLocation); if (actionIsCurrentlyRunning(aNode)) { System.Console.WriteLine(" ACTION is RUNNING : " + aNode.Action.name); //token busy... return(false); } } if (token.outgoingEdge == null) { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null" << endl; //Debug.Log(" NO OUTGOING EDGES...."); //my work here is done *flies away* return(false); } //evaluate guard(s). Normal behavior for fork, but I treat decision nodes here, if there are more paths going out, I will take the first one. if (token.currentLocation.Kind == "fork") { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: fork" << endl; //normal behavior for fork (should not have guard, but hell... it doesn't hurt to check) if (token.outgoingEdge.Guard != null && (!(token.outgoingEdge.Guard.eval(procedure.Activity.Context)))) { return(false); //eval failed } } else { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: no fork" << endl; List <ActivityEdge> outgoingNormal = token.currentLocation.getOutgoingControlFlowEdges(); bool foundWayOut = false; for (int i = 0; i < outgoingNormal.Count; ++i) { //if <no guard> or <guard but evaluates ok> if ((outgoingNormal[i].Guard == null) || (outgoingNormal[i].Guard != null && (outgoingNormal[i].Guard.eval(procedure.Activity.Context)))) { foundWayOut = true; token.outgoingEdge = outgoingNormal[i]; //set new direction, we take the first possible one, remember ? } } if (!foundWayOut) { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: didn't find way out" << endl; return(false); //no way out... leave for later } } ActivityNode nextLocation = token.outgoingEdge.Target; //test allowed action if (nextLocation.Kind == "action") { if ((nextLocation != doneAction) || (!gotTicketToUseAction)) { //not allowed to advance to this action //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: action not allowed" << endl; return(false); } gotTicketToUseAction = false; } //Debug.Log("Next Location : " + nextLocation); //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "adv tok from '" << token->currentLocation->getName() << "' to '" << nextLocation->getName() << "'" << endl; //Advance ActivityEdge dummyActivityEdge = null; token.currentLocation = nextLocation; token.outgoingEdge = dummyActivityEdge; List <ActivityEdge> outgoingAfterAdvance = token.currentLocation.getOutgoingControlFlowEdges(); List <ActivityExecutionToken> nextTokens = new List <ActivityExecutionToken>(); if (token.currentLocation.Kind == "fork") { //time to split token into pieces, in order to follow all fork branches token.forkStack.Add(token.currentLocation); //push this fork to the stack //remove this token from the active list for (int i = 0; i < activeTokens.Count; ++i) { if (activeTokens[i].ToString() == token.ToString()) { activeTokens.RemoveAt(i); break; } } for (int i = 0; i < outgoingAfterAdvance.Count; ++i) { ActivityExecutionToken tok = new ActivityExecutionToken(); tok.currentLocation = token.currentLocation; tok.forkStack = token.forkStack; tok.loopNodeStack = token.loopNodeStack; tok.outgoingEdge = outgoingAfterAdvance[i]; //set outgoing, to know which branch to follow //push to active list activeTokens.Add(tok); //save for further use nextTokens.Add(tok); } } else if (token.currentLocation.Kind == "join") { //we can only pass by a join, if all other branched tokens have arrived in this join //the point is that the number of tokens which have the same last fork as this one, should be the same as the nr of incoming links to this join //i hope i understand this next time i read it List <ActivityEdge> incoming = token.currentLocation.Incoming; //so get the incoming //see which is the last fork of this token ActivityNode lastFork = null; if (token.forkStack.Count > 0) { lastFork = token.forkStack[token.forkStack.Count - 1]; } if (lastFork != null) { //find all tokens that have this fork and see if they all finished their branch // TODO: remember that actually, the forkStacks should be identical for paired tokens... if they're not, we've got a problem.... List <ActivityExecutionToken> finishedTokens = new List <ActivityExecutionToken>(); for (int i = 0; i < activeTokens.Count; ++i) { //if found a token with this last fork if ((activeTokens[i].forkStack.Count > 0) && (activeTokens[i].forkStack[activeTokens[i].forkStack.Count - 1] == lastFork)) { //check to see if it's finished (arrived at the same join) if (activeTokens[i].currentLocation == token.currentLocation) { //add to finished tokens list finishedTokens.Add(activeTokens[i]); } } } //now check to see if the number of found tokens equals the number of incoming links to this join if (finishedTokens.Count == incoming.Count) { //then all should be great.... we can merge all tokens into a single one for (int i = 0; i < finishedTokens.Count; ++i) { //skip the current token, this one will remain if (finishedTokens[i].ToString() == token.ToString()) { continue; } //seek and destroy for (int j = 0; j < activeTokens.Count; ++j) { if (finishedTokens[i].ToString() == activeTokens[j].ToString()) { //destroy activeTokens.RemoveAt(j); } } } if (outgoingAfterAdvance.Count == 1) { token.outgoingEdge = outgoingAfterAdvance[0]; token.forkStack.RemoveAt(token.forkStack.Count - 1);//pop last fork nextTokens.Add(token); } else if (outgoingAfterAdvance.Count > 1) { } } } else { } } else if (token.currentLocation.Kind == "loop") { LoopNode loopNode = (LoopNode)(token.currentLocation); bool skipThisLoopNode = false; if (loopNode.TestedFirst) { if (loopNode.eval()) //thou shall pass { skipThisLoopNode = true; } } ActivityNode initLoop = loopNode.Initial; List <ActivityEdge> outgoingFromInitLoop = null; if (initLoop != null) { outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges(); } if (skipThisLoopNode || (initLoop == null) || (outgoingFromInitLoop.Count < 1)) { //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any if (outgoingAfterAdvance.Count >= 1) { token.outgoingEdge = outgoingAfterAdvance[0]; nextTokens.Add(token); } } else { //enter the loop node, we'll get the edge which exits the loopnode's initial node token.currentLocation = initLoop; token.outgoingEdge = outgoingFromInitLoop[0]; token.loopNodeStack.Add(loopNode); } } else { //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any if (outgoingAfterAdvance.Count >= 1) { token.outgoingEdge = outgoingAfterAdvance[0]; nextTokens.Add(token); } else if (token.loopNodeStack.Count != 0) //check if we're in a loop node { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null, but in loop node" << endl; while (((token.outgoingEdge == null)) && (token.loopNodeStack.Count != 0)) //while we are still in a loopnode and it is finished { LoopNode lastLoop = token.loopNodeStack[token.loopNodeStack.Count - 1]; if (lastLoop.eval()) //test exit condition { //exiting loop node List <ActivityEdge> outgoingFromLoop = lastLoop.getOutgoingControlFlowEdges(); if (outgoingFromLoop.Count != 0) { token.currentLocation = lastLoop; token.outgoingEdge = outgoingFromLoop[0]; } token.loopNodeStack.RemoveAt(token.loopNodeStack.Count - 1); //remove last loop from stack (exit) } else { //restarting loop node ActivityNode initLoop = lastLoop.Initial; List <ActivityEdge> outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges(); token.currentLocation = initLoop; token.outgoingEdge = outgoingFromInitLoop[0]; //it should exist, given the fact that we've entered this loop node already } } if (token.outgoingEdge != null) { nextTokens.Add(token); } } } //continue to advance for (int i = 0; i < nextTokens.Count; ++i) { tryToAdvanceToken(nextTokens[i], doneAction, gotTicketToUseAction); } return(true); }
public void informActionDone(AID agent, string actionName) { ActionNode action = getActionByNameFor(agent, actionName); informActionDone(agent, action); }
public void informActionRunning(AID agent, ActionNode action) { //check if procedure will advance if this action is made bool canAdvance = true; ActionNode actionToRun = null; MascaretApplication.Instance.VRComponentFactory.Log("Start : " + action.getFullName()); // Test if action owned by agent if (action.Partitions[0].name == agentToPartition[agent.toString()].name) { actionToRun = action; } else { MascaretApplication.Instance.VRComponentFactory.Log("This action " + action.getFullName() + " doesn't belong to agent " + agent.toString()); } if (actionToRun != null) { //check if procedure can advance (action is reachable from the previous done actions) List <ActionNode> possibleNextActions = getActionToExecuteFor(agent); for (int i = 0; i < possibleNextActions.Count; ++i) { if (actionToRun == possibleNextActions[i]) { canAdvance = true; break; } } } if (canAdvance) { //save the running action in the list actionsRunning.Add(new KeyValuePair <string, ActionNode>(agent.toString(), action)); //TODO: appologise because the hack is not so beautiful. the good part is that it works fine :) //update next reachable nodes list, if their current location is not a dead end (this caused problems with loopnodes for example...) //-- the problem was that loopnodes must not be restarted/skipped until the effect of its actions is understood. this is not the case with decision nodes for example ActionNode doneAction = action; if (doneAction != null) { bool advancedToken = false; for (int i = 0; i < activeTokens.Count; ++i) { if ((activeTokens[i].outgoingEdge == null) || (activeTokens[i].outgoingEdge.Target.getOutgoingControlFlowEdges().Count == 0)) { continue; //skip deadends } //try to advance //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "> trying to advance token " << (i+1) << "/" << _activeTokens.size() << " from " << _activeTokens[i]->currentLocation->getName() << endl; ActivityExecutionToken token = activeTokens[i]; if (tryToAdvanceToken(token, doneAction, true)) { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << " >> advanced token " << (i+1) << "/" << _activeTokens.size() << " to " << _activeTokens[i]->currentLocation->getName() << endl; activeTokens[i] = token; advancedToken = true; } } if (advancedToken) { //add to "done" list actionsDone.Add(doneAction); MascaretApplication.Instance.VRComponentFactory.Log("AllActionsDone : " + agent.toString()); if (!allActionsDone.ContainsKey(agent.toString())) { allActionsDone.Add(agent.toString(), new List <ActionNode>()); } allActionsDone[agent.toString()].Add(doneAction); MascaretApplication.Instance.VRComponentFactory.Log("allActionsDoneTimestamps : " + agent.toString()); if (!allActionsDoneTimestamps.ContainsKey(agent.toString())) { allActionsDoneTimestamps.Add(agent.toString(), new List <TimeExpression>()); } allActionsDoneTimestamps[agent.toString()].Add(doneAction.CurrentExecution.Finish); MascaretApplication.Instance.VRComponentFactory.Log("Done"); } else { //if (ACTIVATE_GENERAL_DEBUG) cerr << "HUSTON, WE'VE GOT A PROBLEM... no token was advanced for " << doneAction->getName() << endl; } } } }
public List <ActionNode> getActionToExecuteForAll() { //this function simulates token advancement to provide the list of actions that can be executed //an action can be executed if it makes a difference in the procedure (if it enables a token to advance) //prepare output vector List <ActionNode> toExec = new List <ActionNode>(); // StreamWriter file = MascaretApplication.Instance.logfile; //build list of all reachable actions (this list is a super-set which includes the actions to execute). we will filter this list List <ActionNode> allPossibleActionsToExecute = getAllActions(); //backup current activeTokens List <ActivityExecutionToken> activeTokensBackup = new List <ActivityExecutionToken>(); for (int i = 0; i < activeTokens.Count; i++) { activeTokensBackup.Add(activeTokens[i]); } //now filter the list by creating dummy tokens and simulate their advancement for (int i = 0; i < allPossibleActionsToExecute.Count; ++i) { //create dummy list activeTokens.Clear(); for (int j = 0; j < activeTokensBackup.Count; ++j) { //copy the token into a dummy ActivityExecutionToken dummyToken = new ActivityExecutionToken(); dummyToken.currentLocation = activeTokensBackup[j].currentLocation; dummyToken.forkStack = activeTokensBackup[j].forkStack; dummyToken.loopNodeStack = activeTokensBackup[j].loopNodeStack; dummyToken.outgoingEdge = activeTokensBackup[j].outgoingEdge; activeTokens.Add(dummyToken); } //test to see if this action is able to advance a token //file.WriteLine(" NB ACTIVE TOKENS : " + activeTokens.Count); file.Flush(); for (int j = 0; j < activeTokens.Count; ++j) { // file.WriteLine(activeTokens[j].currentLocation.name); file.Flush(); //advance token without the action (just to be sure we don't get fooled into thinking it advanced because of the action when it advances because of some other conditions that came true) //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "advancing with dummy action" << endl; ActionNode dummyActionNode = null; tryToAdvanceToken(activeTokens[j], dummyActionNode, true); //care not about the result //TODO .... check this out //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "advancing dummy token" << endl; //see if the dummy advances with the current action ActivityExecutionToken token = activeTokens[j]; //Debug.Log("CURRENT ACTIVE TOKEN : " + token.currentLocation.name); if (tryToAdvanceToken(token, allPossibleActionsToExecute[i], true)) { //dummy token advanced, so this action is an action to execute activeTokens[j] = token; toExec.Add(allPossibleActionsToExecute[i]); //Debug.Log("New Current Location : " + activeTokens[j].currentLocation.name); //if (ACTIVATE_GENERAL_DEBUG) cerr << "allPossibleActionsToExecute[" << i << "] = " << allPossibleActionsToExecute[i]->getName() << endl; //break; } } } //reinstate backed up activeTokens activeTokens.Clear(); for (int i = 0; i < activeTokensBackup.Count; i++) { activeTokens.Add(activeTokensBackup[i]); } //remove already running nodes :: TODO : check if we should allow this or not.... // file.WriteLine("Action Running : " + actionsRunning.Count); file.Flush(); for (int i = 0; i < actionsRunning.Count; ++i) { for (int j = 0; j < toExec.Count; ++j) { if (actionsRunning[i].Value == toExec[j]) { toExec.RemoveAt(j); j--; } } } return(toExec); }
public void informActionDone(AID agent, ActionNode action) { bool foundAndRemoved = false; //remove from "running" list for (int i = 0; i < actionsRunning.Count; ++i) { if ((actionsRunning[i].Key == agent.toString()) && (actionsRunning[i].Value.getFullName() == action.getFullName())) { actionsRunning.RemoveAt(i); foundAndRemoved = true; break; } } //Debug.Log(" IAD : " + activeTokens.Count); if (foundAndRemoved) { ActionNode doneAction = action; if (doneAction != null) { bool advancedToken = false; for (int i = 0; i < activeTokens.Count; i++) { ActivityExecutionToken token = activeTokens[i]; if (tryToAdvanceToken(token, doneAction, true)) { advancedToken = true; } } if (advancedToken) { //add to "done" list actionsDone.Add(doneAction); allActionsDone[agent.toString()].Add(doneAction); allActionsDoneTimestamps[agent.toString()].Add(doneAction.CurrentExecution.Finish); } else { //if (ACTIVATE_GENERAL_DEBUG) cerr << "HUSTON, WE'VE GOT A PROBLEM... no token was advanced for " << doneAction->getName() << endl; } } } }
public void informActionRunning(AID agent, ActionNode action) { //check if procedure will advance if this action is made bool canAdvance = true; ActionNode actionToRun = null; MascaretApplication.Instance.VRComponentFactory.Log("Start : " + action.getFullName()); // Test if action owned by agent if (action.Partitions[0].name == agentToPartition[agent.toString()].name) actionToRun = action; else MascaretApplication.Instance.VRComponentFactory.Log( "This action " + action.getFullName() + " doesn't belong to agent " + agent.toString()); if (actionToRun != null) { //check if procedure can advance (action is reachable from the previous done actions) List<ActionNode> possibleNextActions = getActionToExecuteFor(agent); for (int i=0; i<possibleNextActions.Count; ++i) { if (actionToRun == possibleNextActions[i]) { canAdvance = true; break; } } } if (canAdvance) { //save the running action in the list actionsRunning.Add(new KeyValuePair<string, ActionNode>(agent.toString(), action)); //TODO: appologise because the hack is not so beautiful. the good part is that it works fine :) //update next reachable nodes list, if their current location is not a dead end (this caused problems with loopnodes for example...) //-- the problem was that loopnodes must not be restarted/skipped until the effect of its actions is understood. this is not the case with decision nodes for example ActionNode doneAction = action; if (doneAction != null) { bool advancedToken = false; for (int i = 0; i < activeTokens.Count; ++i) { if ((activeTokens[i].outgoingEdge == null) || (activeTokens[i].outgoingEdge.Target.getOutgoingControlFlowEdges().Count == 0)) { continue; //skip deadends } //try to advance //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "> trying to advance token " << (i+1) << "/" << _activeTokens.size() << " from " << _activeTokens[i]->currentLocation->getName() << endl; ActivityExecutionToken token = activeTokens[i]; if (tryToAdvanceToken(token, doneAction, true)) { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << " >> advanced token " << (i+1) << "/" << _activeTokens.size() << " to " << _activeTokens[i]->currentLocation->getName() << endl; activeTokens[i] = token; advancedToken = true; } } if (advancedToken) { //add to "done" list actionsDone.Add(doneAction); MascaretApplication.Instance.VRComponentFactory.Log("AllActionsDone : " + agent.toString()); if (!allActionsDone.ContainsKey(agent.toString())) allActionsDone.Add(agent.toString(), new List<ActionNode>()); allActionsDone[agent.toString()].Add(doneAction); MascaretApplication.Instance.VRComponentFactory.Log("allActionsDoneTimestamps : " + agent.toString()); if (!allActionsDoneTimestamps.ContainsKey(agent.toString())) allActionsDoneTimestamps.Add(agent.toString(),new List<TimeExpression>()); allActionsDoneTimestamps[agent.toString()].Add( doneAction.CurrentExecution.Finish); MascaretApplication.Instance.VRComponentFactory.Log("Done"); } else { //if (ACTIVATE_GENERAL_DEBUG) cerr << "HUSTON, WE'VE GOT A PROBLEM... no token was advanced for " << doneAction->getName() << endl; } } } }
public void sendActionDoneMessage(ActionNode action, ProcedureExecution procInfo) { Agent agt = (Agent)(this.Host); ACLMessage procMsg = new ACLMessage(ACLPerformative.INFORM); //we inform at wich time the action finished TimeExpression timestamp = action.CurrentExecution.Finish; procMsg.Timestamp = timestamp; //set ACLMessage content string content = "((done (action "; content += agt.name; content += " "; content += "(" + clean(action.name) + ")"; content += ")))"; procMsg.Content = content; //MascaretApplication.Instance.VRComponentFactory.Log(content); //send message to other agents List<AID> agents = procInfo.getOtherAgents(); for (int iA = 0; iA < agents.Count; iA++) { procMsg.Receivers.Add(agents[iA]); } agt.send(procMsg); }
protected bool tryToAdvanceToken(ActivityExecutionToken token, ActionNode doneAction, bool gotTicketToUseAction) { //TODO : current implementation will fail if the loop node has branches which are not joined together at the end //TODO : setup part of loop nodes not implemented //TODO : careful if the loop node contains only an initial node :: ENDLESS LOOP // Debug.Log(" current token : " + token.currentLocation.name); if (token.currentLocation.Kind == "action") { ActionNode aNode = (ActionNode)(token.currentLocation); if (actionIsCurrentlyRunning(aNode)) { System.Console.WriteLine(" ACTION is RUNNING : " + aNode.Action.name); //token busy... return false; } } if (token.outgoingEdge == null) { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null" << endl; //Debug.Log(" NO OUTGOING EDGES...."); //my work here is done *flies away* return false; } //evaluate guard(s). Normal behavior for fork, but I treat decision nodes here, if there are more paths going out, I will take the first one. if (token.currentLocation.Kind == "fork") { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: fork" << endl; //normal behavior for fork (should not have guard, but hell... it doesn't hurt to check) if (token.outgoingEdge.Guard != null && (!(token.outgoingEdge.Guard.eval(procedure.Activity.Context)))) { return false; //eval failed } } else { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: no fork" << endl; List<ActivityEdge> outgoingNormal = token.currentLocation.getOutgoingControlFlowEdges(); bool foundWayOut = false; for (int i = 0; i < outgoingNormal.Count; ++i) { //if <no guard> or <guard but evaluates ok> if ((outgoingNormal[i].Guard == null) || (outgoingNormal[i].Guard != null && (outgoingNormal[i].Guard.eval(procedure.Activity.Context)))) { foundWayOut = true; token.outgoingEdge = outgoingNormal[i]; //set new direction, we take the first possible one, remember ? } } if (!foundWayOut) { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: didn't find way out" << endl; return false; //no way out... leave for later } } ActivityNode nextLocation = token.outgoingEdge.Target; //test allowed action if (nextLocation.Kind == "action") { if ((nextLocation != doneAction) || (!gotTicketToUseAction)) { //not allowed to advance to this action //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: action not allowed" << endl; return false; } gotTicketToUseAction = false; } //Debug.Log("Next Location : " + nextLocation); //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "adv tok from '" << token->currentLocation->getName() << "' to '" << nextLocation->getName() << "'" << endl; //Advance ActivityEdge dummyActivityEdge = null; token.currentLocation = nextLocation; token.outgoingEdge = dummyActivityEdge; List<ActivityEdge> outgoingAfterAdvance = token.currentLocation.getOutgoingControlFlowEdges(); List<ActivityExecutionToken> nextTokens = new List<ActivityExecutionToken>(); if (token.currentLocation.Kind == "fork") { //time to split token into pieces, in order to follow all fork branches token.forkStack.Add(token.currentLocation); //push this fork to the stack //remove this token from the active list for (int i = 0; i < activeTokens.Count; ++i) { if (activeTokens[i].ToString() == token.ToString()) { activeTokens.RemoveAt(i); break; } } for (int i = 0; i < outgoingAfterAdvance.Count; ++i) { ActivityExecutionToken tok = new ActivityExecutionToken(); tok.currentLocation = token.currentLocation; tok.forkStack = token.forkStack; tok.loopNodeStack = token.loopNodeStack; tok.outgoingEdge = outgoingAfterAdvance[i]; //set outgoing, to know which branch to follow //push to active list activeTokens.Add(tok); //save for further use nextTokens.Add(tok); } } else if (token.currentLocation.Kind == "join") { //we can only pass by a join, if all other branched tokens have arrived in this join //the point is that the number of tokens which have the same last fork as this one, should be the same as the nr of incoming links to this join //i hope i understand this next time i read it List<ActivityEdge> incoming = token.currentLocation.Incoming; //so get the incoming //see which is the last fork of this token ActivityNode lastFork = null; if (token.forkStack.Count > 0) { lastFork = token.forkStack[token.forkStack.Count-1]; } if (lastFork != null) { //find all tokens that have this fork and see if they all finished their branch // TODO: remember that actually, the forkStacks should be identical for paired tokens... if they're not, we've got a problem.... List<ActivityExecutionToken> finishedTokens = new List<ActivityExecutionToken>() ; for (int i=0; i<activeTokens.Count; ++i) { //if found a token with this last fork if ((activeTokens[i].forkStack.Count > 0) && (activeTokens[i].forkStack[activeTokens[i].forkStack.Count-1] == lastFork)) { //check to see if it's finished (arrived at the same join) if (activeTokens[i].currentLocation == token.currentLocation) { //add to finished tokens list finishedTokens.Add(activeTokens[i]); } } } //now check to see if the number of found tokens equals the number of incoming links to this join if (finishedTokens.Count == incoming.Count) { //then all should be great.... we can merge all tokens into a single one for (int i=0; i<finishedTokens.Count; ++i) { //skip the current token, this one will remain if (finishedTokens[i].ToString() == token.ToString()) continue; //seek and destroy for (int j=0; j<activeTokens.Count; ++j) { if (finishedTokens[i].ToString() == activeTokens[j].ToString()) { //destroy activeTokens.RemoveAt( j); } } } if (outgoingAfterAdvance.Count == 1) { token.outgoingEdge = outgoingAfterAdvance[0]; token.forkStack.RemoveAt(token.forkStack.Count - 1);//pop last fork nextTokens.Add(token); } else if (outgoingAfterAdvance.Count > 1) { } } } else { } } else if (token.currentLocation.Kind == "loop") { LoopNode loopNode = (LoopNode)(token.currentLocation); bool skipThisLoopNode = false; if (loopNode.TestedFirst) { if (loopNode.eval()) //thou shall pass { skipThisLoopNode = true; } } ActivityNode initLoop = loopNode.Initial; List<ActivityEdge> outgoingFromInitLoop = null; if (initLoop != null) { outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges(); } if ( skipThisLoopNode || (initLoop == null) || (outgoingFromInitLoop.Count < 1) ) { //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any if (outgoingAfterAdvance.Count >= 1) { token.outgoingEdge = outgoingAfterAdvance[0]; nextTokens.Add(token); } } else { //enter the loop node, we'll get the edge which exits the loopnode's initial node token.currentLocation = initLoop; token.outgoingEdge = outgoingFromInitLoop[0]; token.loopNodeStack.Add(loopNode); } } else { //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any if (outgoingAfterAdvance.Count >= 1) { token.outgoingEdge = outgoingAfterAdvance[0]; nextTokens.Add(token); } else if (token.loopNodeStack.Count != 0) //check if we're in a loop node { //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null, but in loop node" << endl; while (((token.outgoingEdge == null)) && (token.loopNodeStack.Count != 0)) //while we are still in a loopnode and it is finished { LoopNode lastLoop = token.loopNodeStack[token.loopNodeStack.Count - 1]; if (lastLoop.eval()) //test exit condition { //exiting loop node List<ActivityEdge> outgoingFromLoop = lastLoop.getOutgoingControlFlowEdges(); if (outgoingFromLoop.Count != 0) { token.currentLocation = lastLoop; token.outgoingEdge = outgoingFromLoop[0]; } token.loopNodeStack.RemoveAt(token.loopNodeStack.Count -1); //remove last loop from stack (exit) } else { //restarting loop node ActivityNode initLoop = lastLoop.Initial; List<ActivityEdge> outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges(); token.currentLocation = initLoop; token.outgoingEdge = outgoingFromInitLoop[0]; //it should exist, given the fact that we've entered this loop node already } } if (token.outgoingEdge != null) { nextTokens.Add(token); } } } //continue to advance for (int i=0; i<nextTokens.Count; ++i) { tryToAdvanceToken(nextTokens[i], doneAction, gotTicketToUseAction); } return true; }
public void sendActionRealisationMessage(ActionNode action, ProcedureExecution procInfo) { Agent agt = (Agent)(this.Host); ACLMessage procMsg = new ACLMessage(ACLPerformative.INFORM); //we inform at wich time the action start TimeExpression timestamp = action.CurrentExecution.Start; procMsg.Timestamp = timestamp; //set ACLMessage content string content = "((action "; content += agt.name; content += " "; content += "(" + clean(action.name) + ")"; content += "))"; procMsg.Content = content; //send message to other agents List<AID> agents = procInfo.getOtherAgents(); for (int iA = 0; iA < agents.Count; iA++) { procMsg.Receivers.Add(agents[iA]); } agt.send(procMsg); }