asciiflow2/js-lib/state.js

148 lines
3.7 KiB
JavaScript
Raw Normal View History

2014-01-09 20:18:46 +00:00
goog.provide('ascii.State');
/** @const */ var MAX_GRID_SIZE = 1000;
/** @const */ var SPECIAL_VALUE = '+';
/** @const */ var SPECIAL_LINE_H = '\u2014';
/** @const */ var SPECIAL_LINE_V = '|';
/**
2014-01-12 10:37:38 +00:00
* An individual cell within the diagram and it's current value.
*
* @constructor
*/
2014-01-09 20:18:46 +00:00
ascii.Cell = function() {
2014-01-12 10:37:38 +00:00
/** @type {?string} */ this.value = null;
/** @type {?string} */ this.scratchValue = null;
};
/** @return {?string} */
ascii.Cell.prototype.getDrawValue = function() {
return (this.scratchValue != null ? this.scratchValue : this.value);
};
/**
2014-01-12 10:37:38 +00:00
* Holds the entire state of the diagram as a 2D array of cells.
*
* @constructor
*/
2014-01-09 20:18:46 +00:00
ascii.State = function() {
/** @type {Array.<Array.<ascii.Cell>>} */
this.cells = new Array(MAX_GRID_SIZE);
/** @type {Array.<ascii.Cell>} */
this.scratchCells = new Array();
for (var i = 0; i < this.cells.length; i++) {
this.cells[i] = new Array(MAX_GRID_SIZE);
for (var j = 0; j < this.cells[i].length; j++) {
2014-01-09 20:18:46 +00:00
this.cells[i][j] = new ascii.Cell();
}
}
};
2014-01-12 10:37:38 +00:00
/**
* Returns the cell at the given coordinates.
*
* @param {ascii.Vector} vector
2014-01-12 10:48:39 +00:00
* @return {ascii.Cell}
2014-01-12 10:37:38 +00:00
*/
ascii.State.prototype.getCell = function(vector) {
return this.cells[vector.x][vector.y];
};
2014-01-12 11:09:55 +00:00
/**
* Sets the cells value at the given position. Probably shouldn't
* be used directly in many cases. Used drawValue instead.
2014-01-12 11:09:55 +00:00
*
* @param {ascii.Vector} position
* @param {?string} value
2014-01-12 11:09:55 +00:00
*/
ascii.State.prototype.setValue = function(position, value) {
this.getCell(position).value = value;
};
/**
* Sets the cells scratch (uncommitted) value at the given position.
*
* @param {ascii.Vector} position
* @param {?string} value
*/
ascii.State.prototype.drawValue = function(position, value) {
var cell = this.getCell(position);
this.scratchCells.push(cell);
cell.scratchValue = value;
};
/**
* Sets the cells scratch value to be the special value.
*
* @param {ascii.Vector} position
*/
ascii.State.prototype.drawSpecial = function(position) {
this.drawValue(position, SPECIAL_VALUE);
};
/**
* Clears the current drawing scratchpad.
*/
ascii.State.prototype.clearDraw = function() {
for (var i in this.scratchCells) {
this.scratchCells[i].scratchValue = null;
}
this.scratchCells.length = 0;
};
/**
* Returns true if the cell at the given position is special.
*
* @param {ascii.Vector} position
* @return {boolean}
*/
ascii.State.prototype.isSpecial = function(position) {
var cell = this.getCell(position);
var value = cell.scratchValue != null ? cell.scratchValue : cell.value;
return value == SPECIAL_VALUE;
};
/**
* Returns the draw value of a cell at the given position.
*
* @param {ascii.Vector} position
* @return {?string}
*/
ascii.State.prototype.getDrawValue = function(position) {
var cell = this.getCell(position);
var value = cell.scratchValue != null ? cell.scratchValue : cell.value;
if (value != SPECIAL_VALUE) {
return value;
}
// Magic time.
var left = this.isSpecial(position.add(new ascii.Vector(-1, 0)));
var right = this.isSpecial(position.add(new ascii.Vector(1, 0)));
var up = this.isSpecial(position.add(new ascii.Vector(0, -1)));
var down = this.isSpecial(position.add(new ascii.Vector(0, 1)));
if (left && right && !up && !down) {
return SPECIAL_LINE_H;
}
if (!left && !right && up && down) {
return SPECIAL_LINE_V;
}
if (left && right && up && down) {
return SPECIAL_LINE_H;
}
return SPECIAL_VALUE;
};
/**
* Ends the current draw, commiting anything currently drawn the scratchpad.
*/
ascii.State.prototype.commitDraw = function() {
for (var i in this.scratchCells) {
this.scratchCells[i].value = this.scratchCells[i].getDrawValue();
this.scratchCells[i].scratchValue = null;
}
};