Добавлен парсер анимационных переходов

This commit is contained in:
Victor 2015-06-17 19:41:30 +03:00
parent 0191133720
commit bef2e92ed4

View File

@ -0,0 +1,117 @@
package com.annimon.everlastingsummer.transitions;
import java.util.List;
import android.graphics.Color;
import com.annimon.everlastingsummer.Token;
import com.annimon.everlastingsummer.TokenType;
/**
* @author aNNiMON
*/
public final class TransitionsParser {
private static final Token EOF = new Token("", TokenType.EOF);
public static void parse(List<Token> tokens) {
new TransitionsParser(tokens).parse();
}
private final List<Token> tokens;
private final int tokensCount;
private int position;
private TransitionsParser(List<Token> tokens) {
this.tokens = tokens;
tokensCount = tokens.size();
position = 0;
}
private void parse() {
while (!match(TokenType.EOF)) {
if (match(TokenType.DEFINE)) {
final String name = consume(TokenType.WORD).getText();
consume(TokenType.EQ);
final String type = consume(TokenType.WORD).getText();
if ("Fade".equals(type)) parseFade(name);
else if ("Dissolve".equals(type)) parseDissolve(name);
} else {
position++;
}
}
tokens.clear();
}
private void parseFade(String name) {
consume(TokenType.LPAREN);
final int outTime = consumeTime();
// TODO: consume(TokenType.COMMA)
final int holdTime = consumeTime();
// TODO: consume(TokenType.COMMA)
final int inTime = consumeTime();
int color = Color.BLACK;
if (!lookMatch(0, TokenType.RPAREN)) {
// TODO: consume(TokenType.COMMA)
// color? =?
match(TokenType.WORD);
match(TokenType.EQ);
color = consumeColor();
}
consume(TokenType.RPAREN);
Transitions.set(name, new Fade(outTime, holdTime, inTime, color));
}
private void parseDissolve(String name) {
consume(TokenType.LPAREN);
final int time = consumeTime();
consume(TokenType.RPAREN);
Transitions.set(name, new Dissolve(time));
}
private int consumeTime() {
return (int) (1000 * Double.parseDouble(consume(TokenType.NUMBER).getText()));
}
private int consumeColor() {
return parseColor( consume(TokenType.TEXT).getText() );
}
private int parseColor(String text) {
try {
return Color.parseColor(text);
} catch (IllegalArgumentException iae) {
// #fff
int index = text.charAt(0) == '#' ? 1 : 0;
if (text.length() != (index + 3)) return Color.BLACK;
final StringBuilder sb = new StringBuilder(7);
sb.append("#");
sb.append(text.charAt(index)).append(text.charAt(index));
index++;
sb.append(text.charAt(index)).append(text.charAt(index));
index++;
sb.append(text.charAt(index)).append(text.charAt(index));
return parseColor(sb.toString());
}
}
private boolean match(TokenType type) {
if (get(0).getType() != type) return false;
position++;
return true;
}
private Token consume(TokenType type) {
if (get(0).getType() != type) throw new RuntimeException("Ожидался токен " + type + ".");
return tokens.get(position++);
}
private boolean lookMatch(int pos, TokenType type) {
return (type == get(pos).getType());
}
private Token get(int offset) {
if (position + offset >= tokensCount) return EOF;
return tokens.get(position + offset);
}
}