org.catrobat.html5player.client.scripts.Script.java Source code

Java tutorial

Introduction

Here is the source code for org.catrobat.html5player.client.scripts.Script.java

Source

/**
 *  Catroid: An on-device visual programming system for Android devices
 *  Copyright (C) 2010-2014 The Catrobat Team
 *  (<http://developer.catrobat.org/credits>)
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  An additional term exception under section 7 of the GNU Affero
 *  General Public License, version 3, is available at
 *  http://developer.catrobat.org/license_additional_term
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.catrobat.html5player.client.scripts;

import java.util.ArrayList;
import java.util.List;

import org.catrobat.html5player.client.CatrobatDebug;
import org.catrobat.html5player.client.Sprite;
import org.catrobat.html5player.client.Stage;
import org.catrobat.html5player.client.bricks.Brick;
import org.catrobat.html5player.client.bricks.BroadcastBrick;
import org.catrobat.html5player.client.bricks.BroadcastWaitBrick;
import org.catrobat.html5player.client.bricks.ForeverBrick;
import org.catrobat.html5player.client.bricks.LoopEndBrick;
import org.catrobat.html5player.client.bricks.PlaySoundBrick;
import org.catrobat.html5player.client.bricks.RepeatBrick;
import org.catrobat.html5player.client.bricks.StopAllSoundsBrick;
import org.catrobat.html5player.client.bricks.WaitBrick;
import org.catrobat.html5player.client.threading.Callable;
import org.catrobat.html5player.client.threading.CatScheduler;
import org.catrobat.html5player.client.threading.CatThread;

import com.google.gwt.user.client.Timer;

public abstract class Script extends Callable implements Comparable<Script> {

    private static int id = 0;

    protected final Sprite sprite;

    protected final String type;

    protected final String name;

    protected final List<Brick> brickList;

    protected int currentBrickCounter = 0;

    protected boolean scriptFinished = false;

    //##########################################################################

    public Script(Sprite sprite, String type, String name) {
        this.sprite = sprite;
        this.type = type;

        id++;

        this.name = name + id;
        this.brickList = new ArrayList<Brick>();
    }

    public final Sprite getSprite() {
        return sprite;
    }

    public final String getType() {
        return this.type;
    }

    public final String getName() {
        return this.name;
    }

    public Brick getBrick(int position) {
        return brickList.get(position);
    }

    public void addBrick(Brick brick) {
        if (brick != null)
            brickList.add(brick);
    }

    public void addBrick(Brick brick, int position) {
        if (brick != null)
            brickList.add(position, brick);
    }

    public void deleteBrick(int index) {
        brickList.remove(index);
    }

    public List<Brick> getBrickList() {
        return brickList;
    }

    public void addBrickList(List<Brick> brickListToSet) {
        if (!brickListToSet.isEmpty() && brickListToSet != null)
            brickList.addAll(brickListToSet);
    }

    public void addBrickList(List<Brick> brickListToSet, int position) {
        if (!brickListToSet.isEmpty() && brickListToSet != null)
            brickList.addAll(position, brickListToSet);
    }

    //##########################################################################

    /**
     *
     */
    public void run() {
        /** useless since bricks are not removed **/
        if ((currentBrickCounter >= (brickList.size() - 1) && scriptFinished == true) || brickList.isEmpty()) {

            CatrobatDebug.debug("no bricks, work is done");
            setWorkDone();
            return;
        }

        CatrobatDebug.debug(brickList.get(currentBrickCounter).toString() + " : " + getSprite().getName());

        long start = System.currentTimeMillis();

        boolean ignoreBrickCounter = false;
        if ((brickList.get(currentBrickCounter) instanceof BroadcastBrick && this instanceof BroadcastScript
                && ((BroadcastBrick) brickList.get(currentBrickCounter)).getMessage()
                        .equals(((BroadcastScript) this).getBroadcastMessage()))
                || (brickList.get(currentBrickCounter) instanceof BroadcastWaitBrick
                        && this instanceof BroadcastScript
                        && ((BroadcastWaitBrick) brickList.get(currentBrickCounter)).getMessage()
                                .equals(((BroadcastScript) this).getBroadcastMessage()))) {
            ignoreBrickCounter = true;
        }

        brickList.get(currentBrickCounter).execute();

        CatrobatDebug.debug("brick-execution took " + (System.currentTimeMillis() - start) + " ms");
        CatrobatDebug.info("brick execution done");

        long start2 = System.currentTimeMillis();

        CatrobatDebug.info("Redrawing...");

        //redraw screen
        if (isRedrawNecessary()) { // check visibility -sprite.getCostume().isVisible()
            Stage.getInstance().getSpriteManager().redrawScreen();

            CatrobatDebug.debug("Redraw-execution took " + (System.currentTimeMillis() - start2) + " ms");
        }

        if (!ignoreBrickCounter) {
            if (currentBrickCounter < (brickList.size() - 1)) {
                currentBrickCounter++;
            } else {
                setWorkDone();
                scriptFinished = true;
            }

        }
    }

    /**
     *
     * @param time
     */
    public void pause(int time) {
        if (time > 0) {

            CatScheduler.get().getThread(getExecutor()).sleep();
            CatrobatDebug.debug("SCRIPT: " + getExecutor() + " sleep for " + time + " ms...");

            Timer wakeUpTimer = new Timer() {
                public void run() {
                    resume();
                }
            };
            wakeUpTimer.schedule(time);
        }
    }

    /**
     * thread sleeps and will not wake up till resume() gets called
     */
    public void pause() {

        CatScheduler.get().getThread(getExecutor()).sleep();

        CatrobatDebug.debug("SCRIPT: " + getExecutor() + " sleep...");
    }

    /**
     *
     */
    public void resume() {
        CatThread myself = CatScheduler.get().getThread(getExecutor());

        if (myself != null) {
            myself.wake();

            CatrobatDebug.debug("SCRIPT: " + getExecutor() + " wake up...");
        } else {
            //thread has finished execution and is already dead, no need to wake up
        }
    }

    /**
     *
     * @param currentBrick
     */
    public void setCurrentBrick(int currentBrick) {
        this.currentBrickCounter = currentBrick;
    }

    /**
     *
     * @return
     */
    public int getCurrentBrick() {
        return this.currentBrickCounter;
    }

    /**
     *
     * @return
     */
    public RepeatBrick getLastRepeatBrickWithoutLoopEndBrick() {

        int lastBrickIndex = (brickList.size() - 1);

        for (int i = lastBrickIndex; i >= 0; i--) {
            if (brickList.get(i) instanceof RepeatBrick) {
                RepeatBrick brick = (RepeatBrick) brickList.get(i);

                if (brick.getLoopEndBrick() == null)
                    return brick;
            }
        }

        return null;
    }

    /**
     *
     * @return
     */
    public ForeverBrick getLastForeverBrickWithoutLoopEndlessBrick() {

        int lastBrickIndex = (brickList.size() - 1);

        for (int i = lastBrickIndex; i >= 0; i--) {
            if (brickList.get(i) instanceof ForeverBrick) {
                ForeverBrick brick = (ForeverBrick) brickList.get(i);

                if (brick.getLoopEndlessBrick() == null)
                    return brick;
            }
        }

        return null;
    }

    /**
     *
     * @return
     */
    public String getExecutor() {
        return super.getExecutorName();
    }

    /**
     *
     * @return
     */
    public boolean hasScriptFinished() {
        return scriptFinished;
    }

    /**
     * Returns if a redraw of the screen is necessary
     * @return true if a redraw is necessary, false otherwise
     */
    private boolean isRedrawNecessary() {

        Brick executedBrick = brickList.get(currentBrickCounter);

        boolean redraw = true;

        if (executedBrick instanceof BroadcastBrick)
            redraw = false;
        else if (executedBrick instanceof BroadcastWaitBrick)
            redraw = false;
        else if (executedBrick instanceof RepeatBrick)
            redraw = false;
        else if (executedBrick instanceof ForeverBrick)
            redraw = false;
        else if (executedBrick instanceof LoopEndBrick)
            redraw = false;
        else if (executedBrick instanceof WaitBrick)
            redraw = false;
        else if (executedBrick instanceof PlaySoundBrick)
            redraw = false;
        else if (executedBrick instanceof StopAllSoundsBrick)
            redraw = false;

        return redraw;
    }

    //##########################################################################

    @Override
    public int compareTo(Script other) {
        if (other == null)
            return -255;
        if (this.type == null && other.type != null) {
            return 128;
        } else if (this.type != null && other.type == null) {
            return -128;
        } else if (this.type != null && !this.type.equals(other.type)) {
            return this.type.compareTo(other.type);
        }
        if (this.name == null && other.name != null) {
            return 64;
        } else if (this.name != null && other.name == null) {
            return -64;
        } else if (this.name != null && !this.name.equals(other.name)) {
            return this.name.compareTo(other.name);
        }
        return 0;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());

        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Script other = (Script) obj;
        if (type == null) {
            if (other.type != null)
                return false;
        } else if (!type.equals(other.type))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    public int getId() {
        return id;
    }

}