-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
66,263 additions
and
1 deletion.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# initializes the canvas, with top-left corner (200,70) and | ||
# dimensions 360x360 | ||
canvas 200 70 360 360 | ||
# declares a rectangle shape named R | ||
shape R rectangle | ||
# describes the motions of shape R, between two moments of animation: | ||
# t == tick | ||
# (x,y) == position | ||
# (w,h) == dimensions | ||
# (r,g,b) == color (with values between 0 and 255) | ||
# start end | ||
# -------------------------- ---------------------------- | ||
# t x y w h r g b t x y w h r g b | ||
motion R 1 200 200 50 100 255 0 0 10 200 200 50 100 255 0 0 | ||
motion R 10 200 200 50 100 255 0 0 50 300 300 50 100 255 0 0 | ||
motion R 50 300 300 50 100 255 0 0 51 300 300 50 100 255 0 0 | ||
motion R 51 300 300 50 100 255 0 0 70 300 300 25 100 255 0 0 | ||
motion R 70 300 300 25 100 255 0 0 100 200 200 25 100 255 0 0 | ||
|
||
shape C ellipse | ||
motion C 6 440 70 120 60 0 0 255 # start state | ||
20 440 70 120 60 0 0 255 # end state | ||
motion C 20 440 70 120 60 0 0 255 50 440 250 120 60 0 0 255 | ||
motion C 50 440 250 120 60 0 0 255 70 440 370 120 60 0 170 85 | ||
motion C 70 440 370 120 60 0 170 85 80 440 370 120 60 0 255 0 | ||
motion C 80 440 370 120 60 0 255 0 100 440 370 120 60 0 255 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package com.company.util; | ||
|
||
public interface AnimationBuilder<Doc> { | ||
/** | ||
* Constructs a final document. | ||
* @return the newly constructed document | ||
*/ | ||
Doc build(); | ||
|
||
|
||
/** | ||
* Specify the bounding box to be used for the animation. | ||
* @param x The leftmost x value | ||
* @param y The topmost y value | ||
* @param width The width of the bounding box | ||
* @param height The height of the bounding box | ||
* @return This {@link AnimationBuilder} | ||
*/ | ||
AnimationBuilder<Doc> setBounds(int x, int y, int width, int height); | ||
|
||
/** | ||
* Adds a new shape to the growing document. | ||
* | ||
* @param name The unique name of the shape to be added. | ||
* No shape with this name should already exist. | ||
* @param type The type of shape (e.g. "ellipse", "rectangle") to be added. | ||
* The set of supported shapes is unspecified, but should | ||
* include "ellipse" and "rectangle" as a minimum. | ||
* @return This {@link AnimationBuilder} | ||
*/ | ||
AnimationBuilder<Doc> declareShape(String name, String type); | ||
|
||
/** | ||
* Adds a transformation to the growing document. | ||
* | ||
* @param name The name of the shape (added with {@link AnimationBuilder#declareShape}) | ||
* @param t1 The start time of this transformation | ||
* @param x1 The initial x-position of the shape | ||
* @param y1 The initial y-position of the shape | ||
* @param w1 The initial width of the shape | ||
* @param h1 The initial height of the shape | ||
* @param r1 The initial red color-value of the shape | ||
* @param g1 The initial green color-value of the shape | ||
* @param b1 The initial blue color-value of the shape | ||
* @param t2 The end time of this transformation | ||
* @param x2 The final x-position of the shape | ||
* @param y2 The final y-position of the shape | ||
* @param w2 The final width of the shape | ||
* @param h2 The final height of the shape | ||
* @param r2 The final red color-value of the shape | ||
* @param g2 The final green color-value of the shape | ||
* @param b2 The final blue color-value of the shape | ||
* @return This {@link AnimationBuilder} | ||
*/ | ||
AnimationBuilder<Doc> addMotion(String name, | ||
int t1, int x1, int y1, int w1, int h1, int r1, int g1, int b1, | ||
int t2, int x2, int y2, int w2, int h2, int r2, int g2, int b2); | ||
|
||
/** | ||
* Adds an individual keyframe to the growing document. | ||
* @param name The name of the shape (added with {@link AnimationBuilder#declareShape}) | ||
* @param t The time for this keyframe | ||
* @param x The x-position of the shape | ||
* @param y The y-position of the shape | ||
* @param w The width of the shape | ||
* @param h The height of the shape | ||
* @param r The red color-value of the shape | ||
* @param g The green color-value of the shape | ||
* @param b The blue color-value of the shape | ||
* @return This {@link AnimationBuilder} | ||
*/ | ||
AnimationBuilder<Doc> addKeyframe(String name, | ||
int t, int x, int y, int w, int h, int r, int g, int b); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package com.company.util; | ||
|
||
import java.util.Objects; | ||
import java.util.Scanner; | ||
import java.util.regex.Pattern; | ||
|
||
/** | ||
* A helper to read animation data and construct an animation from it. | ||
*/ | ||
public class AnimationReader { | ||
/** | ||
* A factory for producing new animations, given a source of shapes and a | ||
* builder for constructing animations. | ||
* | ||
* <p> | ||
* The input file format consists of two types of lines: | ||
* <ul> | ||
* <li>Shape lines: the keyword "shape" followed by two identifiers (i.e. | ||
* alphabetic strings with no spaces), giving the unique name of the shape, | ||
* and the type of shape it is.</li> | ||
* <li>Motion lines: the keyword "motion" followed by an identifier giving the name | ||
* of the shape to move, and 16 integers giving the initial and final conditions of the motion: | ||
* eight numbers giving the time, the x and y coordinates, the width and height, | ||
* and the red, green and blue color values at the start of the motion; followed by | ||
* eight numbers for the end of the motion. See {@link AnimationBuilder#addMotion}</li> | ||
* </ul> | ||
* </p> | ||
* | ||
* @param readable The source of data for the animation | ||
* @param builder A builder for helping to construct a new animation | ||
* @param <Doc> The main model interface type describing animations | ||
* @return | ||
*/ | ||
public static <Doc> Doc parseFile(Readable readable, AnimationBuilder<Doc> builder) { | ||
Objects.requireNonNull(readable, "Must have non-null readable source"); | ||
Objects.requireNonNull(builder, "Must provide a non-null AnimationBuilder"); | ||
Scanner s = new Scanner(readable); | ||
// Split at whitespace, and ignore # comment lines | ||
s.useDelimiter(Pattern.compile("(\\p{Space}+|#.*)+")); | ||
while (s.hasNext()) { | ||
String word = s.next(); | ||
switch (word) { | ||
case "canvas": | ||
readCanvas(s, builder); | ||
break; | ||
case "shape": | ||
readShape(s, builder); | ||
break; | ||
case "motion": | ||
readMotion(s, builder); | ||
break; | ||
default: | ||
throw new IllegalStateException("Unexpected keyword: " + word + s.nextLine()); | ||
} | ||
} | ||
return builder.build(); | ||
} | ||
|
||
private static <Doc> void readCanvas(Scanner s, AnimationBuilder<Doc> builder) { | ||
int[] vals = new int[4]; | ||
String[] fieldNames = {"left", "top", "width", "height"}; | ||
for (int i = 0; i < 4; i++) { | ||
vals[i] = getInt(s, "Canvas", fieldNames[i]); | ||
} | ||
builder.setBounds(vals[0], vals[1], vals[2], vals[3]); | ||
} | ||
|
||
private static <Doc> void readShape(Scanner s, AnimationBuilder<Doc> builder) { | ||
String name; | ||
String type; | ||
if (s.hasNext()) { | ||
name = s.next(); | ||
} else { | ||
throw new IllegalStateException("Shape: Expected a name, but no more input available"); | ||
} | ||
if (s.hasNext()) { | ||
type = s.next(); | ||
} else { | ||
throw new IllegalStateException("Shape: Expected a type, but no more input available"); | ||
} | ||
builder.declareShape(name, type); | ||
} | ||
|
||
private static <Doc> void readMotion(Scanner s, AnimationBuilder<Doc> builder) { | ||
String[] fieldNames = new String[]{ | ||
"initial time", | ||
"initial x-coordinate", "initial y-coordinate", | ||
"initial width", "initial height", | ||
"initial red value", "initial green value", "initial blue value", | ||
"final time", | ||
"final x-coordinate", "final y-coordinate", | ||
"final width", "final height", | ||
"final red value", "final green value", "final blue value", | ||
}; | ||
int[] vals = new int[16]; | ||
String name; | ||
if (s.hasNext()) { | ||
name = s.next(); | ||
} else { | ||
throw new IllegalStateException("Motion: Expected a shape name, but no more input available"); | ||
} | ||
for (int i = 0; i < 16; i++) { | ||
vals[i] = getInt(s, "Motion", fieldNames[i]); | ||
} | ||
builder.addMotion(name, | ||
vals[0], vals[1], vals[2 ], vals[3 ], vals[4 ], vals[5 ], vals[6 ], vals[7 ], | ||
vals[8], vals[9], vals[10], vals[11], vals[12], vals[13], vals[14], vals[15]); | ||
} | ||
|
||
private static int getInt(Scanner s, String label, String fieldName) { | ||
if (s.hasNextInt()) { | ||
return s.nextInt(); | ||
} else if (s.hasNext()) { | ||
throw new IllegalStateException( | ||
String.format("%s: expected integer for %s, got: %s", label, fieldName, s.next())); | ||
} else { | ||
throw new IllegalStateException( | ||
String.format("%s: expected integer for %s, but no more input available", | ||
label, fieldName)); | ||
} | ||
} | ||
} |
Oops, something went wrong.