| 624 | workDone = false; |
| 625 | for (int i = 0; i < a.size(); i++) { |
| 626 | Object q = a.get(i); |
| 627 | if (q instanceof Vec2 || q instanceof Vec3) { |
| 628 | o.add(q); |
| 629 | } else if (q instanceof Collection) { |
| 630 | // note, we'll keep doing this over and over |
| 631 | List<Object> qq = transform((Collection) q, transformation); |
| 632 | workDone |= !qq.equals(q); |
| 633 | o.add(qq); |
| 634 | } else { |
| 635 | boolean done = false; |
| 636 | for (Function<Object, Object> f : transformation) { |
| 637 | try { |
| 638 | Object m = f.apply(q); |
| 639 | if (m != null) { |
| 640 | o.add(m); |
| 641 | done = true; |
| 642 | workDone |= !m.equals(q); |
| 643 | break; |
| 644 | } |
| 645 | } catch (Throwable e) { |
| 646 | System.out.println(" exception thrown in transformation, continuing on"); |
| 647 | e.printStackTrace(); |
| 648 | } |
| 649 | } |
| 650 | if (!done) { |
| 651 | throw new IllegalArgumentException(" can't transform " + q); |
| 652 | } |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | a = o; |
| 657 | o = new ArrayList<>(); |
| 658 | |
| 659 | } while (workDone); |
| 660 | return a; |
| 661 | } |
| 662 | |
| 663 | /** |
| 664 | * take 'many things' and turn them into a line based on the formatting string. |
| 665 | * <p> |
| 666 | * 'm' - moveTo, needs a Vec2 or a Vec3 'l' - lineTo, needs a Vec2 or a Vec3 'c' - cubicTo, needs 3 Vec2 or Vec3; 's' - smoothTo, needs 1 Vec2 or Vec3 '*' will loop the previous instruction; |
| 667 | * '+' will loop the whole set of instructions 'd' will drop a Vec3; 'C' — is a cubic segment that consumes the next two instructions as well (e.g. you need to write 12C to do the same as |
| 668 | * 'c') |
| 669 | * until you run out of Vec3 inputs; 't' — dispatches based on the tag of a TaggedVec3; 'b' pushes the previous 'm'oveTo onto the stack to be consumed again by futher instructions (e.g |
| 670 | * 'mlllbl' draws a closed quadrilateral) |
| 671 | */ |