git @ Cat's Eye Technologies Wierd / master dialect / wierd-jnc / impl / wierd-jnc.js / src / yoob / cursor.js
master

Tree @master (Download .tar.gz)

cursor.js @masterraw · history · blame

/*
 * This file is part of yoob.js version 0.7
 * Available from https://github.com/catseye/yoob.js/
 * This file is in the public domain.  See http://unlicense.org/ for details.
 */
if (window.yoob === undefined) yoob = {};

/*
 * An object representing a position and direction in some space.  The space
 * may be one-dimensional (a yoob.Tape, or a string representing a program
 * source) or a two-dimensional Cartesian space (such as a yoob.Playfield.)
 * A direction vector accompanies the position, so the cursor can "know which
 * way it's headed", but this facility need not be used.
 *
 * A cursor contains a built-in simple view, i.e. it knows how to render
 * itself on a canvas (drawContext method) or in the midst of HTML text
 * (wrapText method).  These methods are used by the view classes (playfield,
 * tape, source, etc.)  The default methods draw basic block cursors in the
 * colour given by the fillStyle attribute, if present, or a light green if
 * it is not defined.
 */
yoob.Cursor = function() {
    this.init = function(x, y, dx, dy) {
        this.x = x;
        this.y = y;
        this.dx = dx;
        this.dy = dy;
        return this;
    };

    this.clone = function() {
        return new yoob.Cursor().init(this.x, this.y, this.dx, this.dy);
    };

    this.getX = function() {
        return this.x;
    };

    this.getY = function() {
        return this.y;
    };

    this.setX = function(x) {
        this.x = x;
    };

    this.setY = function(y) {
        this.y = y;
    };

    this.isHeaded = function(dx, dy) {
        return this.dx === dx && this.dy === dy;
    };

    this.advance = function() {
        this.x += this.dx;
        this.y += this.dy;
    };

    this.rotateClockwise = function() {
        if (this.dx === 0 && this.dy === -1) {
            this.dx = 1; this.dy = -1;
        } else if (this.dx === 1 && this.dy === -1) {
            this.dx = 1; this.dy = 0;
        } else if (this.dx === 1 && this.dy === 0) {
            this.dx = 1; this.dy = 1;
        } else if (this.dx === 1 && this.dy === 1) {
            this.dx = 0; this.dy = 1;
        } else if (this.dx === 0 && this.dy === 1) {
            this.dx = -1; this.dy = 1;
        } else if (this.dx === -1 && this.dy === 1) {
            this.dx = -1; this.dy = 0;
        } else if (this.dx === -1 && this.dy === 0) {
            this.dx = -1; this.dy = -1;
        } else if (this.dx === -1 && this.dy === -1) {
            this.dx = 0; this.dy = -1;
        }
    };

    this.rotateCounterclockwise = function() {
        if (this.dx === 0 && this.dy === -1) {
            this.dx = -1; this.dy = -1;
        } else if (this.dx === -1 && this.dy === -1) {
            this.dx = -1; this.dy = 0;
        } else if (this.dx === -1 && this.dy === 0) {
            this.dx = -1; this.dy = 1;
        } else if (this.dx === -1 && this.dy === 1) {
            this.dx = 0; this.dy = 1;
        } else if (this.dx === 0 && this.dy === 1) {
            this.dx = 1; this.dy = 1;
        } else if (this.dx === 1 && this.dy === 1) {
            this.dx = 1; this.dy = 0;
        } else if (this.dx === 1 && this.dy === 0) {
            this.dx = 1; this.dy = -1;
        } else if (this.dx === 1 && this.dy === -1) {
            this.dx = 0; this.dy = -1;
        }
    };

    this.rotateDegrees = function(degrees) {
        while (degrees > 0) {
            this.rotateCounterclockwise();
            degrees -= 45;
        }
    };

    /* from yoob.TapeHead; may go away or change slightly */
    this.move = function(delta) {
        this.x += delta;
    };

    this.moveLeft = function(amount) {
        if (amount === undefined) amount = 1;
        this.x -= amount;
    };

    this.moveRight = function(amount) {
        if (amount === undefined) amount = 1;
        this.x += amount;
    };

    this.read = function() {
        if (!this.tape) return undefined;
        return this.tape.get(this.x);
    };

    this.write = function(value) {
        if (!this.tape) return;
        this.tape.put(this.x, value);
    };

    /*
     * For HTML views.  Override if you like.
     */
    this.wrapText = function(text) {
        var fillStyle = this.fillStyle || "#50ff50";
        return '<span style="background: ' + fillStyle + '">' +
               text + '</span>';
    };

    /*
     * For canvas views.  Override if you like.
     */
    this.drawContext = function(ctx, x, y, cellWidth, cellHeight) {
        ctx.fillStyle = this.fillStyle || "#50ff50";
        ctx.fillRect(x, y, cellWidth, cellHeight);
    };
}