/**
* 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 /**
* 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;
import org.catrobat.html5player.client.formulaeditor.UserVariablesContainer;
import org.catrobat.html5player.client.scripts.Script;
import org.catrobat.html5player.client.threading.CatScheduler;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.TextArea;
public class Stage {
private static final int TEXT_LINE_HEIGHT = 10;
private static Stage instance = null;
private final SpriteManager spriteManager;
private final MessageContainer messageContainer;
private String projectNumber;
private Canvas rootCanvas;
private TextArea logBox;
private Script currentScript = null;
private Sprite currentSprite = null;
private UserVariablesContainer userVariables;
public UserVariablesContainer getUserVariables() {
return userVariables;
}
public Sprite getCurrentSprite() {
return currentSprite;
}
public void setCurrentSprite(Sprite sprite) {
currentSprite = sprite;
}
public Script getCurrentScript() {
return currentScript;
}
public void setCurrentScript(Script script) {
if (script == null) {
currentScript = null;
} else if (currentSprite.getScriptIndex(script) != -1) {
currentScript = script;
}
}
private Stage() {
spriteManager = new SpriteManager();
messageContainer = new MessageContainer();
userVariables = new UserVariablesContainer();
}
public static Stage getInstance() {
if (instance == null) {
instance = new Stage();
}
return instance;
}
//##########################################################################
/**
* Parses the project-XML, adds all StartScripts to the scheduler, loads
* all images which where added to the ImageHandler and waits for them to
* load. After the images got loaded, the scheduler gets started.
*
* @param projectXml
*/
public void start(String projectXml) {
Parser parser = new Parser();
long start = System.currentTimeMillis();
parser.parseXML(spriteManager, projectXml);
if(!parser.isParsingComplete())
{
return;
}
CatrobatDebug.debug("XML got parsed");
CatrobatDebug.debug("Parsing took " + (System.currentTimeMillis() - start) + " ms");
ImageHandler.get().loadImages();
CatrobatDebug.debug("Actual number of attached images: " + ImageHandler.get().getNumberOfAttachedImages());
//add StartScripts to scheduler
spriteManager.playCatroid();
// spriteManager.debugSpriteCostumes();
CatrobatDebug.debug("Actual scripts waiting to run: " + CatScheduler.get().getThreadCount());
//wait for the images to load, then start the scheduler
Timer imagesLoadedTimer = new Timer() {
@Override
public void run() {
if(ImageHandler.get().areImagesLoaded() || ImageHandler.get().hasNothingToDo()) {
CatrobatDebug.debug(ImageHandler.get().getNumberImagesLoaded() + " images are loaded, now starting scheduler...");
ImageHandler.get().reset();
//revive scheduler, so it can run again
CatScheduler.get().reviveScheduler();
//start CatScheduler
Scheduler.get().scheduleFixedDelay(CatScheduler.get(), CatScheduler.SCHEDULE_DELAY);
this.cancel();
}
else {
CatrobatDebug.debug("ImageHandler not finished loading...");
CatrobatDebug.debug(ImageHandler.get().getStatus());
if(ImageHandler.get().hasLoadingFailed()) {
CatrobatDebug.error("ImageHandler couldn't load an image");
log("ImageHandler couldn't load an image");
this.cancel();
loadingFailure();
}
}
}
};
imagesLoadedTimer.scheduleRepeating(50);
}
/**
*
*/
public void displayLoadingImage() {
CatrobatDebug.debug("displayLoadingImage...");
//ImageHandler.get().addImage("loadgif", "images/ajax-loader.gif");
Image i = new Image( "images/ajax-loader.gif");
ImageHandler.get().newImage("loadgif", i);
ImageHandler.get().loadImages();
//wait for the image to load, then draw it
Timer imageLoadedTimer = new Timer() {
@Override
public void run() {
if(ImageHandler.get().areImagesLoaded()) {
CatrobatDebug.debug("Loading gif ready to display");
Image image = ImageHandler.get().getImage("loadgif");
ImageHandler.get().reset();
Scene.get().clearCanvas();
Scene.get().drawImage(image, getStageMiddleX(),
getStageMiddleY(), image.getWidth(),
image.getHeight(), 1);
// Scene.get().update();
this.cancel();
}
}
};
imageLoadedTimer.scheduleRepeating(10);
}
/**
*
*/
public void clearStage() {
userVariables = new UserVariablesContainer();
defaultLogBoxSettings();
CatrobatDebug.debug("Spritemanager contains " + spriteManager.getSpriteList().size() + " sprites");
CatrobatDebug.debug("MessageContainer holds " + messageContainer.getMessages().size() + " messages");
CatrobatDebug.info("Now clearing the stage...");
//clear messageContainer
messageContainer.clear();
//remove all sprites and stop currently running sounds
spriteManager.clearSprites();
//kill all currently running threads and the scheduler
CatScheduler.get().killScheduler();
//dump all loaded and unloaded images
ImageHandler.get().dumpAllImages();
ImageHandler.get().reset();
CatrobatDebug.debug("Spritemanager contains " + spriteManager.getSpriteList().size() + " sprites");
CatrobatDebug.debug("MessageContainer holds " + messageContainer.getMessages().size() + " messages");
CatrobatDebug.debug("Actually scheduled threads: " + CatScheduler.get().getThreadCount());
CatrobatDebug.debug("Actually loaded images " + ImageHandler.get().getTotalNumberOfLoadedImages());
CatrobatDebug.debug("Number of attached images " + ImageHandler.get().getNumberOfAttachedImages());
CatrobatDebug.info("Stage got cleared...");
}
/**
* Display an error message on the canvas
*/
private void loadingFailure() {
String message = "Error: Couldn't load an image";
Scene.get().clearCanvas();
Scene.get().setFont("12pt Calibri");
Scene.get().write(message, getStageMiddleX(), getStageMiddleY(), "center");
CatrobatDebug.info("Error message written to canvas");
// Scene.get().update();
}
//##########################################################################
/**
*
* @param message
*/
public void log(String message) {
if (message == null)
return;
String logText = logBox.getText();
if (logText == null)
logText = "";
if(logText == "")
{
logText = message.trim();
}
else
{
logText += "\n" + message.trim();
}
logBox.setText(logText);
logBox.setSize("400px", (logText.split("\\n").length * TEXT_LINE_HEIGHT) + "px");
}
public void defaultLogBoxSettings() {
if(this.logBox != null) {
logBox.setText("");
logBox.setSize("400px", TEXT_LINE_HEIGHT + "px");
logBox.setVisible(false);
}
}
//##########################################################################
public void setProjectNumber(String number) {
this.projectNumber = number;
}
public String getProjectNumber() {
return this.projectNumber;
}
public SpriteManager getSpriteManager() {
return spriteManager;
}
public void setCanvas(Canvas canvas) {
rootCanvas = canvas;
}
public Canvas getCanvas() {
return rootCanvas;
}
public int getStageMiddleX() {
int middleX = (int)rootCanvas.getCoordinateSpaceWidth() / 2;
return middleX;
}
public int getStageMiddleY() {
int middleY = (int)rootCanvas.getCoordinateSpaceHeight() / 2;
return middleY;
}
public MessageContainer getMessageContainer() {
return messageContainer;
}
public void setLogBox(TextArea logBox) {
this.logBox = logBox;
}
}