public void stop() { if (activation.procedure().isTask()) { throw NonLocalExit$.MODULE$; } if (activation.procedure().topLevel()) { // In the BehaviorSpace case, there are two cases: stop // used inside a procedure called from the go commands, // and stop used in the go commands themselves. (People // probably shouldn't be doing the latter, since they // could just use a stop condition, but you know somebody // will try...) If stop is used in the go commands // themselves, then the call to returnFromProcedure below // means that __experimentstepend won't run. Thus we need // to set job.stopping to true ourselves, if we just // returned from a top level procedure. If I've analyzed // this correctly, setting it to true will have no effect // in other settings besides BehaviorSpace. // - ST 3/8/06, 8/30/07 job.stopping = true; finished = true; } returnFromProcedure(); // this is so that we can stop our enclosing forever // button if we're immediately inside one. __foreverbuttonend // will be looking for this to be true and if it is, will // stop the button. this flag is reset to false by // _return and _report, so the next time a procedure // returns normally, the forever button will no longer // stop since "stop" wasn't used within a procedure called // directly by the button. - ST // It's also used to stop a BehaviorSpace run, using // __experimentstepend. - ST 3/8/06 stopping = true; }
public Object callReporterProcedure(Activation newActivation) { boolean oldInReporterProcedure = inReporterProcedure; Command command = null; inReporterProcedure = true; // so use of "ask" will create an exclusive job activation = newActivation; ip = 0; try { do { command = activation.procedure().code()[ip]; if ((agentBit & command.agentBits) == 0) { command.throwAgentClassException(this, agent.kind()); } command.perform(this); if (command.world.comeUpForAir) { comeUpForAir(command); } } while (!finished && job.result == null); } catch (NonLocalExit$ e) { // do nothing } catch (LogoException ex) { EngineException.rethrow(ex, this, command); } finally { inReporterProcedure = oldInReporterProcedure; } ip = activation.returnAddress(); activation = activation.parent(); Object result = job.result; job.result = null; return result; }
public void runExclusiveJob(AgentSet agentset, int address) { new ExclusiveJob(job.owner, agentset, activation.procedure(), address, this, job.random).run(); // this next check is here to handle an obscure special case: // check if the child has (gasp!) killed its parent // - ST 6/27/05, 1/10/07 if (agent.id == -1) { finished = true; } }
// this had to be made public so that workspace.Evaluator could call it when // running command thunks. - JC 6/11/10 public void runtimeError(Exception ex) { try { Instruction instruction = null; Context context = null; if (ex instanceof EngineException) { instruction = ((EngineException) ex).instruction(); context = ((EngineException) ex).context(); } if (instruction == null) { instruction = activation.procedure().code()[ip]; } if (context == null) { context = this; } activation.procedure().code()[ip].workspace.runtimeError(job.owner, context, instruction, ex); } catch (RuntimeException ex2) { // well we tried to report the original exception to the user, // but a new exception happened. so we'll report the original // using plan B. - ST 8/29/07 org.nlogo.util.Exceptions.handle(ex); } }
// this method runs until the context is finished void runExclusive() { if (agent.id == -1) // is our agent dead? { finished = true; return; } Command command = null; try { do { command = activation.procedure().code()[ip]; if ((agentBit & command.agentBits) == 0) { command.throwAgentClassException(this, agent.kind()); } command.perform(this); if (command.world.comeUpForAir) { comeUpForAir(command); } } while (!finished); } catch (LogoException ex) { EngineException.rethrow(ex, this, command); } }
// this method runs only until a command switches void stepConcurrent() { if (agent.id == -1) // is our agent dead? { finished = true; return; } Command command = null; try { do { command = activation.procedure().code()[ip]; if ((agentBit & command.agentBits) == 0) { command.throwAgentClassException(this, agent.kind()); } command.perform(this); if (command.world.comeUpForAir) { comeUpForAir(command); } } while (!command.switches && !finished); } catch (LogoException ex) { EngineException.rethrow(ex, this, command); } catch (StackOverflowError ex) { throw new EngineException(this, "stack overflow (recursion too deep)"); } }