File indexing completed on 2024-05-12 16:23:26
0001 /*************************************************************************** 0002 * Copyright (C) 2013 by Linuxstopmotion contributors; * 0003 * see the AUTHORS file for details. * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 0021 #include "scenevector.h" 0022 0023 #include <exception> 0024 0025 #include "scene.h" 0026 #include "frame.h" 0027 0028 class SceneOutOfRangeException : public std::exception { 0029 public: 0030 SceneOutOfRangeException() { 0031 } 0032 const char* what() const throw() { 0033 return "Internal error: Scene out of range!"; 0034 } 0035 }; 0036 0037 SceneVector::SceneVector() : totalSoundCount(0) { 0038 } 0039 0040 SceneVector::~SceneVector() { 0041 clear(); 0042 } 0043 0044 void SceneVector::clear() { 0045 for (std::vector<Scene*>::iterator i = scenes.begin(); 0046 i != scenes.end(); ++i) { 0047 delete *i; 0048 } 0049 scenes.clear(); 0050 totalSoundCount = 0; 0051 } 0052 0053 int SceneVector::sceneCount() const { 0054 return scenes.size(); 0055 } 0056 0057 void SceneVector::addScene(int where, Scene* newScene) { 0058 if (where < 0 || sceneCount() < where) 0059 throw SceneOutOfRangeException(); 0060 scenes.insert(scenes.begin() + where, newScene); 0061 totalSoundCount += newScene->soundCount(); 0062 } 0063 0064 void SceneVector::addScene(int where) { 0065 preallocateScenes(1); 0066 scenes.insert(scenes.begin() + where, new Scene()); 0067 } 0068 0069 void SceneVector::preallocateScenes(int count) { 0070 scenes.reserve(sceneCount() + count); 0071 } 0072 0073 Scene* SceneVector::removeScene(int from) { 0074 int sc = sceneCount(); 0075 if (from < 0 || sc <= from) 0076 throw SceneOutOfRangeException(); 0077 Scene* s = scenes[from]; 0078 scenes.erase(scenes.begin() + from); 0079 totalSoundCount -= s->soundCount(); 0080 return s; 0081 } 0082 0083 void SceneVector::moveScene(int from, int to) { 0084 int size = sceneCount(); 0085 if (from < 0 || size <= from || to < 0 || size < to) 0086 throw SceneOutOfRangeException(); 0087 Scene* s = removeScene(from); 0088 if (from < to) 0089 --to; 0090 addScene(to, s); 0091 } 0092 0093 const Scene* SceneVector::getScene(int which) const { 0094 if (which < 0 || sceneCount() <= which) 0095 throw SceneOutOfRangeException(); 0096 return scenes[which]; 0097 } 0098 0099 Scene* SceneVector::getMutableScene(int which) { 0100 if (which < 0 || sceneCount() <= which) 0101 throw SceneOutOfRangeException(); 0102 return scenes[which]; 0103 } 0104 0105 int SceneVector::frameCount(int scene) const { 0106 return getScene(scene)->getSize(); 0107 } 0108 0109 void SceneVector::addFrame(int scene, int where, Frame* frame) { 0110 getMutableScene(scene)->addFrame(frame, where); 0111 totalSoundCount += frame->soundCount(); 0112 } 0113 0114 void SceneVector::addFrames(int scene, int where, 0115 const std::vector<Frame*>& frames) { 0116 getMutableScene(scene)->addFrames(where, frames); 0117 for (std::vector<Frame*>::const_iterator i = frames.begin(); 0118 i != frames.end(); ++i) { 0119 totalSoundCount += (*i)->soundCount(); 0120 } 0121 } 0122 0123 void SceneVector::preallocateFrames(int scene, int count) { 0124 getMutableScene(scene)->preallocateFrames(count); 0125 } 0126 0127 Frame* SceneVector::removeFrame(int scene, int frame) { 0128 Frame* r = getMutableScene(scene)->removeFrame(frame); 0129 totalSoundCount -= r->soundCount(); 0130 return r; 0131 } 0132 0133 void SceneVector::removeFrames(int scene, int frame, int count, 0134 std::vector<Frame*>& out) { 0135 int start = static_cast<int>(out.size()); 0136 getMutableScene(scene)->removeFrames(frame, count, out); 0137 for (std::vector<Frame*>::const_iterator i = out.begin() + start; 0138 i != out.end(); ++i) { 0139 totalSoundCount -= (*i)->soundCount(); 0140 } 0141 } 0142 0143 void SceneVector::moveFrames(int fromScene, int fromFrame, int frameCount, 0144 int toScene, int toFrame) { 0145 Scene* from = getMutableScene(fromScene); 0146 Scene* to = getMutableScene(toScene); 0147 const int fromSize = from->getSize(); 0148 const int toSize = to->getSize(); 0149 if (fromSize < fromFrame + frameCount 0150 || toSize < toFrame) 0151 throw FrameOutOfRangeException(); 0152 if (toScene != fromScene) { 0153 preallocateFrames(toScene, frameCount); 0154 // this will do for now, even though it is quadratic 0155 for (int i = 0; i != frameCount; ++i) { 0156 Frame* f = from->removeFrame(fromFrame); 0157 to->addFrame(f, toFrame + i); 0158 } 0159 } else if (toFrame < fromFrame) { 0160 // this will do for now, even though it is stupid 0161 for (int i = 0; i != frameCount; ++i) { 0162 Frame* f = from->removeFrame(fromFrame + i); 0163 to->addFrame(f, toFrame + i); 0164 } 0165 } else if (fromFrame + frameCount < toFrame) { 0166 // this will do for now, even though it is stupid 0167 for (int i = 0; i != frameCount; ++i) { 0168 // perform a rotation 0169 Frame* f = from->removeFrame(fromFrame); 0170 to->addFrame(f, toFrame - 1); 0171 } 0172 } 0173 } 0174 0175 int SceneVector::soundCount(int scene, int frame) const { 0176 return getScene(scene)->getFrame(frame)->soundCount(); 0177 } 0178 0179 void SceneVector::addSound(int scene, int frame, int soundNumber, 0180 Sound* sound) { 0181 getMutableScene(scene)->addSound(frame, soundNumber, sound); 0182 ++totalSoundCount; 0183 } 0184 0185 const char* SceneVector::setSoundName(int scene, int frame, int soundNumber, 0186 const char* soundName) { 0187 return getMutableScene(scene)->setSoundName(frame, soundNumber, soundName); 0188 } 0189 0190 Sound* SceneVector::removeSound(int scene, int frame, int soundNumber) { 0191 Sound* r = getMutableScene(scene)->removeSound(frame, soundNumber); 0192 if (r) 0193 --totalSoundCount; 0194 return r; 0195 } 0196 0197 void SceneVector::replaceImage(int sceneNumber, int frameNumber, 0198 WorkspaceFile& otherImage) { 0199 getMutableScene(sceneNumber)->replaceImage(frameNumber, otherImage); 0200 } 0201 0202 int SceneVector::soundCount() const { 0203 return totalSoundCount; 0204 } 0205 0206 void SceneVector::accept(FileNameVisitor& v) const { 0207 for (std::vector<Scene*>::const_iterator i = scenes.begin(); 0208 i != scenes.end(); 0209 ++i) { 0210 (*i)->accept(v); 0211 } 0212 } 0213 0214 const char* SceneVector::getImagePath(int scene, int frame) const { 0215 return getScene(scene)->getFrame(frame)->getImagePath(); 0216 } 0217 0218 void SceneVector::playSounds(int scene, int frame, AudioDriver* driver) const { 0219 getScene(scene)->getFrame(frame)->playSounds(driver); 0220 }