package jadex.rules.rulesystem; import jadex.commons.ICommand; import jadex.commons.ISteppable; import jadex.commons.concurrent.Executor; import jadex.commons.concurrent.IExecutable; import jadex.commons.concurrent.IThreadPool; import jadex.commons.concurrent.ThreadPoolFactory; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * A rule system executor can execute rule systems on a separate thread. */ public class RuleSystemExecutor implements ISteppable { //-------- attributes -------- /** The stepmode flag. */ protected boolean stepmode; /** Flag indicating that a single step should be performed. */ protected boolean dostep; /** The agenda. */ protected RuleSystem rulesystem; /** The executor. */ protected Executor executor; /** The breakpoints (i.e. rules that set the interpreter to step mode, when activated). */ protected Set breakpoints; /** The breakpoint commands. */ protected ICommand[] breakpointcommands; //-------- constructors -------- /** * Executor for rule systems. */ public RuleSystemExecutor(final RuleSystem rulesystem, boolean stepmode) { this(rulesystem, stepmode, null); } /** * Executor for rule systems. */ public RuleSystemExecutor(final RuleSystem rulesystem, boolean stepmode, IThreadPool threadpool) { this.rulesystem = rulesystem; this.executor = new Executor(threadpool!=null? threadpool: ThreadPoolFactory.createThreadPool(), new IExecutable() { public boolean execute() { // Check for breakpoints, if any. if(breakpoints!=null) { Iterator it = rulesystem.getAgenda().getActivations().iterator(); while(it.hasNext()) { IRule rule = ((Activation)it.next()).getRule(); if(breakpoints.contains(rule.getName())) { setStepmode(true); // Notify listeners if(breakpointcommands!=null) { for(int i=0; i<breakpointcommands.length; i++) { breakpointcommands[i].execute(rule); } } break; } } } if(!isStepmode() || RuleSystemExecutor.this.dostep) { RuleSystemExecutor.this.dostep = false; // synchronized(monitor) { rulesystem.getAgenda().fireRule(); rulesystem.getState().expungeStaleObjects(); rulesystem.getState().notifyEventListeners(); // for(Iterator it= rulesystem.getState().getObjects(); it.hasNext(); ) // System.out.println(it.next()); } } return !rulesystem.getAgenda().isEmpty() && !isStepmode(); } }); setStepmode(stepmode); } //-------- steppable interface -------- /** * Execute a step. */ public void doStep() { dostep = true; if(stepmode) executor.execute(); } /** * Set the stepmode. * @param stepmode True for stepmode. */ public void setStepmode(boolean stepmode) { this.stepmode = stepmode; if(!stepmode) executor.execute(); } /** * Test if in stepmode. * @return True, if in stepmode. */ public boolean isStepmode() { return this.stepmode; } /** * Add a breakpoint to the interpreter. */ public void addBreakpoint(Object rule) { if(breakpoints==null) breakpoints = new HashSet(); breakpoints.add(rule); } /** * Remove a breakpoint from the interpreter. */ public void removeBreakpoint(Object rule) { if(breakpoints.remove(rule) && breakpoints.isEmpty()) breakpoints = null; } /** * Check if a rule is a breakpoint for the interpreter. */ public boolean isBreakpoint(Object rule) { return breakpoints!=null && breakpoints.contains(rule); } /** * Add a command to be executed, when a breakpoint is reached. */ public void addBreakpointCommand(ICommand command) { if(breakpointcommands==null) { breakpointcommands = new ICommand[]{command}; } else { ICommand[] newarray = new ICommand[breakpointcommands.length+1]; System.arraycopy(breakpointcommands, 0, newarray, 0, breakpointcommands.length); newarray[breakpointcommands.length] = command; breakpointcommands = newarray; } } //-------- methods -------- /** * Get the rule system. * @return The rule system. */ public RuleSystem getRulesystem() { return this.rulesystem; } }