package org.goko.core.gcode.rs274ngcv3.element; import org.goko.core.common.exception.GkException; import org.goko.core.common.exception.GkTechnicalException; import org.goko.core.gcode.element.IInstructionProvider; import org.goko.core.gcode.element.IInstructionSetIterator; import org.goko.core.gcode.rs274ngcv3.IRS274NGCService; import org.goko.core.gcode.rs274ngcv3.context.GCodeContext; import org.goko.core.gcode.rs274ngcv3.instruction.AbstractInstruction; public class InstructionIterator implements IInstructionSetIterator<GCodeContext, AbstractInstruction>{ /** The context */ private GCodeContext context; /** The used instruction provider */ private IInstructionProvider<AbstractInstruction, InstructionSet> provider; /** Current iterator index */ private int providerCurrentIndex; /** Current iterator index */ private int instructionSetCurrentIndex; /** GCode service */ private IRS274NGCService service; public InstructionIterator(IInstructionProvider<AbstractInstruction, InstructionSet> provider, GCodeContext context, IRS274NGCService service){ this.provider = provider; this.service = service; this.providerCurrentIndex = 0; this.instructionSetCurrentIndex = 0; this.initialize(context); } /** (inheritDoc) * @see org.goko.core.gcode.element.IInstructionSetIterator#initialize(org.goko.core.gcode.element.IGCodeContext) */ @Override public void initialize(GCodeContext context) { this.context = context; } /** (inheritDoc) * @see org.goko.core.gcode.element.IInstructionSetIterator#hasNext() */ @Override public boolean hasNext() { return internalHasNext(providerCurrentIndex, instructionSetCurrentIndex); } /** * Internal hasNext implementation * @param providerCurrentIndex the input index in the provider list * @param instructionSetCurrentIndex the input index in the instruction set * @return boolean */ private boolean internalHasNext(int providerCurrentIndex, int instructionSetCurrentIndex) { if(providerCurrentIndex < provider.size()){ if(instructionSetCurrentIndex < provider.get(providerCurrentIndex).size()){ return true; }else{ return internalHasNext(providerCurrentIndex + 1, 0); } } return false; } /** (inheritDoc) * @see org.goko.core.gcode.element.IInstructionSetIterator#next() */ @Override public AbstractInstruction next() throws GkException { if(!hasNext()){ throw new GkTechnicalException("Out of bound exception. Iterator reached the end of the instruction list"); } AbstractInstruction instruction = null; instruction = provider.get(providerCurrentIndex).get(instructionSetCurrentIndex); context = service.update(context, instruction); // Update pointers incrementInstructionPointer(); return instruction; } /** * Increment the pointer on the current instruction */ private void incrementInstructionPointer(){ if(providerCurrentIndex < provider.size()){ if(instructionSetCurrentIndex >= provider.get(providerCurrentIndex).size() - 1){ incrementProviderPointer(); }else{ instructionSetCurrentIndex = instructionSetCurrentIndex + 1; } } } /** * Increment the pointer on the current instruction set */ private void incrementProviderPointer(){ providerCurrentIndex = providerCurrentIndex + 1; instructionSetCurrentIndex = -1; incrementInstructionPointer(); } /** (inheritDoc) * @see org.goko.core.gcode.element.IInstructionSetIterator#getContext() */ @Override public GCodeContext getContext() { return context; } }