@Before
 public final void setUp() throws Exception {
   engine = new DefaultKnittingEngine(knittingFactory);
   List<Needle> needles = new ArrayList<Needle>();
   needles.add(initialNeedle);
   engine.useNeedles(needles);
   engine.castOn(40, true);
   assertOriginalState();
   save();
 }
  @Test
  public void checkNeedleReturned() throws Exception {
    Needle newNeedle = knittingFactory.createNeedle("new-needle", NeedleStyle.CIRCULAR);
    List<Needle> needles = new ArrayList<Needle>();
    needles.add(newNeedle);
    engine.useNeedles(needles);
    engine.castOn(5);

    restore();
    // note that needles which were not in the engine
    // are not affected by the restore
    assertEquals(5, newNeedle.getTotalStitches());
  }
Example #3
0
 /**
  * A repeat is necessary only when its until condition has not yet been met.
  *
  * @param repeat
  * @param engine
  * @return
  */
 protected boolean isRepeatNecessary(Repeat repeat, KnittingEngine engine) {
   Until until = repeat.getUntil();
   Integer value = repeat.getValue();
   switch (until) {
     case TIMES:
       // repeat if we have to repeat more than 0 times
       return value > 0;
     case BEFORE_END:
       return engine.getStitchesRemainingInRow() > value;
     case END:
       return engine.getStitchesRemainingInRow() > 0;
     case BEFORE_GAP:
       return engine.getStitchesToGap() > value;
     case BEFORE_MARKER:
       return engine.getStitchesToNextMarker() > value;
     case MARKER:
       return engine.getStitchesToNextMarker() > 0;
     default:
       throw new RuntimeException("The until value [" + until + "] has not been properly coded");
   }
 }
  @Test(expected = NoGapFoundException.class)
  public void checkGapsRemoved() throws Exception {
    engine.startNewRow();
    engine.knit(10);
    engine.turn();
    engine.knit(10);
    engine.turn();
    assertEquals(10, engine.getStitchesToGap());

    // restore
    restore();
    engine.startNewRow();
    engine.getStitchesToGap();
  }
 @Test
 public void checkRowPositionReset() throws Exception {
   engine.startNewRow();
   engine.knit(40);
   engine.endRow();
   // now right-side facing
   engine.startNewRow();
   engine.knit(10);
   engine.designateEndOfRow();
   engine.endRow();
 }
 private void assertOriginalState() {
   // capture state right after the cast-on row before startNewRow() is
   // called
   assertEquals(1, engine.getTotalRowsCompleted());
   assertEquals(1, engine.getCurrentRowNumber());
   assertEquals(40, engine.getTotalNumberOfStitchesInRow());
   assertEquals(0, engine.getStitchesRemainingInRow());
   assertEquals(Direction.FORWARDS, engine.getDirection());
   assertEquals(KnittingShape.FLAT, engine.getKnittingShape());
 }
Example #7
0
  protected InlineOperation handle(Repeat oldRepeat) {

    // initialize variables for this method
    KnittingEngine engine = renderingContext.getEngine();
    Until until = oldRepeat.getUntil();
    Integer value = oldRepeat.getValue();

    // ensure that we can continue to analyze this instruction for charting
    if (dynamicFirstRowCastOn && until != Until.TIMES) {
      log.info(
          "Cannot chart this instruction because it is both defined in the header (i.e. without a knitting context) "
              + "and the first row has a repeat section that requires a knitting context."
              + "This can be fixed either by declaring the 'until' attribute of the repeat in the first row to be of type 'times', "
              + "or by including the repeats in the directions "
              + "section of the pattern instead of in the header.");
      return null;
    }
    if (currentlyRepeating) {
      log.info("Cannot currently chart nested repeats. This feature may be expanded in the future");
      return null;
    }

    // see if we need to repeat at all. If not, just return "0 repeats"
    if (!isRepeatNecessary(oldRepeat, engine)) {
      return new Repeat(Until.TIMES, 0);
    }

    // at this point, we have to do the repeat (1 or more times)
    currentlyRepeating = true;

    // start gathering up information for the new repeat. Our goal is to
    // convert all repeats
    // into an until value that represents TIMES. This is so we won't need
    // the engine to chart.
    List<DiscreteInlineOperation> newOperations = new ArrayList<DiscreteInlineOperation>();

    // gather current (pre-repeat) state
    Object engineState = engine.save();
    int originalChartWidth = this.currentRowInfo.getRowWidth();

    // walk through all the instructions of this repeat ONCE to calculate
    // the advance and increase count. If we find a work-even, remove
    // the repeat all together and completely expand the row
    boolean contextualOperationFound = false;
    for (InlineOperation operation : oldRepeat.getOperations()) {
      if (!contextualOperationFound && operation instanceof WorkEven) {
        contextualOperationFound = true;
        // if we find out there are contextual operations, clear out
        // newOperations
        // and wait for the actual repeat. We'll gather that info then.
        newOperations.clear();
        break;
      }
      InlineOperation newOperation = handle(operation);
      // if a non-discrete inline operation or null is returned, we cannot
      // chart, so return null up the chain
      if (!(newOperation instanceof DiscreteInlineOperation)) {
        return null;
      }
      newOperations.add((DiscreteInlineOperation) newOperation);
    }

    // reset the engine to the state before we repeated once
    engine.restore(engineState);
    this.currentRowInfo.setRowWidth(originalChartWidth);

    int counter = 0;
    switch (until) {
      case TIMES:
        for (int i = 0; i < value; i++) {
          // advanceAndIncrease(advanceCount, increaseCount);
          for (InlineOperation operation : oldRepeat.getOperations()) {
            DiscreteInlineOperation newOperation = (DiscreteInlineOperation) handle(operation);
            if (contextualOperationFound) {
              newOperations.add(newOperation);
            }
          }
        }
        counter = value;
        break;
      case BEFORE_END:
        while (engine.getStitchesRemainingInRow() > value) {
          // advanceAndIncrease(advanceCount, increaseCount);
          for (InlineOperation operation : oldRepeat.getOperations()) {
            DiscreteInlineOperation newOperation = (DiscreteInlineOperation) handle(operation);
            if (contextualOperationFound) {
              newOperations.add(newOperation);
            }
          }
          counter++;
        }
        break;
      case END:
        while (engine.getStitchesRemainingInRow() > 0) {
          // advanceAndIncrease(advanceCount, increaseCount);
          for (InlineOperation operation : oldRepeat.getOperations()) {
            DiscreteInlineOperation newOperation = (DiscreteInlineOperation) handle(operation);
            if (contextualOperationFound) {
              newOperations.add(newOperation);
            }
          }
          counter++;
        }
        break;
      case BEFORE_GAP:
        while (engine.getStitchesToGap() > value) {
          // advanceAndIncrease(advanceCount, increaseCount);
          for (InlineOperation operation : oldRepeat.getOperations()) {
            DiscreteInlineOperation newOperation = (DiscreteInlineOperation) handle(operation);
            if (contextualOperationFound) {
              newOperations.add(newOperation);
            }
          }
          counter++;
        }
        break;
      case BEFORE_MARKER:
        while (engine.getStitchesToNextMarker() > value) {
          // advanceAndIncrease(advanceCount, increaseCount);
          for (InlineOperation operation : oldRepeat.getOperations()) {
            DiscreteInlineOperation newOperation = (DiscreteInlineOperation) handle(operation);
            if (contextualOperationFound) {
              newOperations.add(newOperation);
            }
          }
          counter++;
        }
        break;
      case MARKER:
        while (engine.getStitchesToNextMarker() > 0) {
          // advanceAndIncrease(advanceCount, increaseCount);
          for (InlineOperation operation : oldRepeat.getOperations()) {
            DiscreteInlineOperation newOperation = (DiscreteInlineOperation) handle(operation);
            if (contextualOperationFound) {
              newOperations.add(newOperation);
            }
          }
          counter++;
        }
        break;
      default:
        throw new RuntimeException("The until value [" + until + "] has not been properly coded");
    }

    currentlyRepeating = false;
    if (contextualOperationFound) {
      // make a stitch group out of all of the gathered operations if
      // we are dealing with work even operations
      return new OperationGroup(newOperations);
    } else {
      Repeat newRepeat = new Repeat();
      newRepeat.setOperations(newOperations);
      newRepeat.setUntil(Until.TIMES);
      newRepeat.setValue(counter);
      return newRepeat;
    }
  }
Example #8
0
  protected Row analyzeRow(Row originalRow) {
    KnittingEngine engine = renderingContext.getEngine();
    // can't handle short rows
    if (originalRow.isShortRow()) {
      return null;
    }
    // can't handle colors (right now)
    if (originalRow.getYarnIdRef() != null) {
      return null;
    }

    List<InlineOperation> newOperations = new ArrayList<InlineOperation>();
    Row newRow = new Row(originalRow, newOperations);
    this.currentRowInfo = new RowInfo();

    // Begin the row for the engine
    if (dynamicFirstRowCastOn) {
      // if this is an instruction definition, infer the intended shape
      // from what is specified by the first row's shape.
      // If nothing is specified, flat knitting is assumed.
      if (originalRow.getType() != null) {
        this.shape = originalRow.getType();
      }
      // cast on one stitch so that we can start a new row below
      engine.castOn(1, false);
    }
    engine.startNewRow();
    if (this.startingSide == null) {
      this.startingSide = Side.RIGHT;
      if (dynamicFirstRowCastOn && originalRow.getSide() == Side.WRONG) {
        this.startingSide = Side.WRONG;
        engine.knit();
        engine.endRow();
        engine.startNewRow();
      } else if (engine.getDirection() == Direction.BACKWARDS) {
        this.startingSide = Side.WRONG;
      }
    }

    // Walk through all of the row's operations and see how it affects the
    // counts
    for (InlineOperation operation : originalRow.getOperations()) {
      InlineOperation newOperation = handle(operation);
      // if null is returned, we cannot chart, so return null up the chain
      if (newOperation == null) {
        return null;
      }
      newOperations.add(newOperation);
    }

    // End the row for the engine
    if (dynamicFirstRowCastOn) {
      // remove the "extra" stitch we created in order to start the row.
      engine.reverseSlip(1);
      // don't swallow the real stitch's nature
      StitchNature stitchNature = engine.peekAtNextStitch().getCurrentNature();
      if (stitchNature == StitchNature.PURL) {
        engine.purlTwoTogether();
      } else {
        engine.knitTwoTogether();
      }
      // now pretend like all is normal
      dynamicFirstRowCastOn = false;
    }
    engine.endRow();

    // if this row pushed the bounds of the previously recorded maximum
    // width, record the new max width
    if (currentRowInfo.getRowWidth() > maxWidth) {
      maxWidth = currentRowInfo.getRowWidth();
    }

    // if (!repeatInCurrentRow) {
    // resetGlobalRepeatTracker();
    // }

    this.rowInfos.add(currentRowInfo);
    return newRow;
  }
  @Test(expected = NoMarkerFoundException.class)
  public void checkMarkersRemoved() throws Exception {
    engine.startNewRow();
    engine.knit(10);
    engine.placeMarker();
    engine.knit(15);
    engine.placeMarker();
    engine.knit(15);
    engine.endRow();
    engine.startNewRow();
    assertEquals(15, engine.getStitchesToNextMarker());

    // restore
    restore();
    engine.startNewRow();
    engine.getStitchesToNextMarker();
  }
 @Test
 public void checkStitchCountsAndKnittingShapeRestored() throws Exception {
   engine.startNewRow();
   assertEquals(Direction.BACKWARDS, engine.getDirection());
   engine.knit(10);
   for (int i = 0; i < 10; i++) {
     engine.knitTwoTogether();
   }
   engine.knit(10);
   assertEquals(2, engine.getCurrentRowNumber());
   assertEquals(30, engine.getTotalNumberOfStitchesInRow());
   engine.endRow();
   assertEquals(2, engine.getTotalRowsCompleted());
   engine.declareRoundKnitting();
   assertEquals(KnittingShape.ROUND, engine.getKnittingShape());
   engine.startNewRow();
   engine.knit(5);
 }
 private void restore() throws Exception {
   engine.restore(memento);
 }
 private void save() throws Exception {
   memento = engine.save();
 }