/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2016 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.catroid.content; import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; import org.catrobat.catroid.content.bricks.Brick; import org.catrobat.catroid.content.bricks.IfLogicBeginBrick; import org.catrobat.catroid.content.bricks.IfLogicElseBrick; import org.catrobat.catroid.content.bricks.IfLogicEndBrick; import org.catrobat.catroid.content.bricks.IfThenLogicBeginBrick; import org.catrobat.catroid.content.bricks.IfThenLogicEndBrick; import org.catrobat.catroid.content.bricks.LoopBeginBrick; import org.catrobat.catroid.content.bricks.LoopEndBrick; import org.catrobat.catroid.content.bricks.NestingBrick; import org.catrobat.catroid.content.bricks.ScriptBrick; import org.catrobat.catroid.content.bricks.UserBrick; import java.io.Serializable; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public abstract class Script implements Serializable { private static final long serialVersionUID = 1L; protected ArrayList<Brick> brickList; protected transient ScriptBrick brick; protected boolean commentedOut = false; public Script() { brickList = new ArrayList<>(); } public abstract Script copyScriptForSprite(Sprite copySprite); public void doCopy(Sprite copySprite, Script cloneScript) { ArrayList<Brick> cloneBrickList = cloneScript.getBrickList(); cloneScript.commentedOut = commentedOut; for (Brick brick : getBrickList()) { Brick copiedBrick = brick.copyBrickForSprite(copySprite); if (!(copiedBrick instanceof ScriptBrick)) { copiedBrick.setCommentedOut(brick.isCommentedOut()); } if (copiedBrick instanceof IfLogicEndBrick) { setIfBrickReferences((IfLogicEndBrick) copiedBrick, (IfLogicEndBrick) brick); } else if (copiedBrick instanceof IfThenLogicEndBrick) { setIfThenBrickReferences((IfThenLogicEndBrick) copiedBrick, (IfThenLogicEndBrick) brick); } else if (copiedBrick instanceof LoopEndBrick) { setLoopBrickReferences((LoopEndBrick) copiedBrick, (LoopEndBrick) brick); } cloneBrickList.add(copiedBrick); } } protected Object readResolve() { return this; } public abstract ScriptBrick getScriptBrick(); public void run(Sprite sprite, SequenceAction sequence) { if (this.isCommentedOut()) { return; } ArrayList<SequenceAction> sequenceList = new ArrayList<>(); sequenceList.add(sequence); for (int i = 0; i < brickList.size(); i++) { if (brickList.get(i).isCommentedOut()) { continue; } List<SequenceAction> actions = brickList.get(i).addActionToSequence(sprite, sequenceList.get(sequenceList.size() - 1)); if (actions != null) { for (SequenceAction action : actions) { if (sequenceList.contains(action)) { sequenceList.remove(action); } else { sequenceList.add(action); } } } } } public void addBrick(Brick brick) { if (brick != null) { brickList.add(brick); updateUserBricksIfNecessary(brick); } } public void addBrick(int position, Brick brick) { if (brick != null) { brickList.add(position, brick); updateUserBricksIfNecessary(brick); } } private void updateUserBricksIfNecessary(Brick brick) { if (brick instanceof UserBrick) { UserBrick userBrick = (UserBrick) brick; userBrick.updateUserBrickParametersAndVariables(); } } public void removeInstancesOfUserBrick(UserBrick userBrickToRemove) { LinkedList<Brick> toRemove = new LinkedList<>(); for (Brick brick : brickList) { if (brick instanceof UserBrick) { UserBrick userBrick = (UserBrick) brick; if (userBrick.getDefinitionBrick() == userBrickToRemove.getDefinitionBrick()) { toRemove.add(brick); } } } for (Brick brick : toRemove) { brickList.remove(brick); } } public void removeBricks(List<Brick> bricksToRemove) { for (Brick brick : bricksToRemove) { removeBrick(brick); } } public void removeBrick(Brick brick) { brickList.remove(brick); } public ArrayList<Brick> getBrickList() { return brickList; } public int getRequiredResources() { int resources = Brick.NO_RESOURCES; for (Brick brick : brickList) { if (!brick.isCommentedOut()) { resources |= brick.getRequiredResources(); } } return resources; } public boolean containsBrickOfType(Class<?> type) { for (Brick brick : brickList) { //Log.i(TAG, brick.REQUIRED_RESSOURCES + ""); if (brick.getClass() == type) { return true; } } return false; } public int containsBrickOfTypeReturnsFirstIndex(Class<?> type) { int i = 0; for (Brick brick : brickList) { if (brick.getClass() == type) { return i; } i++; } return -1; } // // public boolean containsBluetoothBrick() { // for (Brick brick : brickList) { // if ((brick instanceof NXTMotorActionBrick) || (brick instanceof NXTMotorTurnAngleBrick) // || (brick instanceof NXTMotorStopBrick) || (brick instanceof NXTPlayToneBrick)) { // return true; // } // } // return false; // } public Brick getBrick(int index) { if (index < 0 || index >= brickList.size()) { return null; } return brickList.get(index); } public void setBrick(ScriptBrick brick) { this.brick = brick; } protected void setIfBrickReferences(IfLogicEndBrick copiedIfEndBrick, IfLogicEndBrick originalIfEndBrick) { List<NestingBrick> ifBrickList = originalIfEndBrick.getAllNestingBrickParts(true); IfLogicBeginBrick copiedIfBeginBrick = ((IfLogicBeginBrick) ifBrickList.get(0)).getCopy(); IfLogicElseBrick copiedIfElseBrick = ((IfLogicElseBrick) ifBrickList.get(1)).getCopy(); copiedIfBeginBrick.setIfElseBrick(copiedIfElseBrick); copiedIfBeginBrick.setIfEndBrick(copiedIfEndBrick); copiedIfElseBrick.setIfBeginBrick(copiedIfBeginBrick); copiedIfElseBrick.setIfEndBrick(copiedIfEndBrick); copiedIfEndBrick.setIfBeginBrick(copiedIfBeginBrick); copiedIfEndBrick.setIfElseBrick(copiedIfElseBrick); } protected void setIfThenBrickReferences(IfThenLogicEndBrick copiedIfEndBrick, IfThenLogicEndBrick originalIfEndBrick) { List<NestingBrick> ifBrickList = originalIfEndBrick.getAllNestingBrickParts(true); IfThenLogicBeginBrick copiedIfBeginBrick = (IfThenLogicBeginBrick) ((IfThenLogicBeginBrick) ifBrickList.get(0)).getCopy(); copiedIfBeginBrick.setIfThenEndBrick(copiedIfEndBrick); copiedIfEndBrick.setIfThenBeginBrick(copiedIfBeginBrick); } protected void setLoopBrickReferences(LoopEndBrick copiedBrick, LoopEndBrick originalBrick) { List<NestingBrick> loopBrickList = originalBrick.getAllNestingBrickParts(true); LoopBeginBrick copiedLoopBeginBrick = ((LoopBeginBrick) loopBrickList.get(0)).getCopy(); copiedLoopBeginBrick.setLoopEndBrick(copiedBrick); copiedBrick.setLoopBeginBrick(copiedLoopBeginBrick); } public boolean isCommentedOut() { return commentedOut; } public void setCommentedOut(boolean commentedOut) { this.commentedOut = commentedOut; if (commentedOut) { for (Brick brick : brickList) { brick.setCommentedOut(commentedOut); } } } public List<Brick> getBricksRequiringResources(int resource) { List<Brick> resourceBrickList = new ArrayList<Brick>(); for (Brick brick : brickList) { if ((brick.getRequiredResources() & resource) != 0) { resourceBrickList.add(brick); } } return resourceBrickList; } }