00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "sprite/sprite_manager.hpp"
00018
00019 #include "lisp/parser.hpp"
00020 #include "sprite/sprite.hpp"
00021 #include "util/file_system.hpp"
00022 #include "util/reader.hpp"
00023
00024 #include <sstream>
00025 #include <stdexcept>
00026
00027
00028 SpriteManager::SpriteManager() :
00029 sprites()
00030 {
00031 }
00032
00033 SpriteManager::~SpriteManager()
00034 {
00035 for(Sprites::iterator i = sprites.begin(); i != sprites.end(); ++i) {
00036 delete i->second;
00037 }
00038 }
00039
00040 SpritePtr
00041 SpriteManager::create(const std::string& name)
00042 {
00043 Sprites::iterator i = sprites.find(name);
00044 SpriteData* data;
00045 if(i == sprites.end()) {
00046
00047 data = load(name);
00048 if(data == NULL) {
00049 std::stringstream msg;
00050 msg << "Sprite '" << name << "' not found.";
00051 throw std::runtime_error(msg.str());
00052 }
00053 } else {
00054 data = i->second;
00055 }
00056
00057 return SpritePtr(new Sprite(*data));
00058 }
00059
00060 SpriteData*
00061 SpriteManager::load(const std::string& filename)
00062 {
00063 lisp::Parser parser;
00064 const lisp::Lisp* root;
00065
00066 try {
00067 if(filename.size() >= 7 && filename.compare(filename.size() - 7, 7, ".sprite") == 0) {
00068
00069 root = parser.parse(filename);
00070 } else {
00071
00072 std::stringstream lisptext;
00073 lisptext << "(supertux-sprite (action "
00074 << "(name \"default\") "
00075 << "(images \"" << FileSystem::basename(filename) << "\")))";
00076
00077 root = parser.parse(lisptext, "SpriteManager::load");
00078 }
00079 } catch(const std::exception& e) {
00080 std::ostringstream msg;
00081 msg << "Parse error when trying to load sprite '" << filename
00082 << "': " << e.what() << "\n";
00083 throw std::runtime_error(msg.str());
00084 }
00085
00086 const lisp::Lisp* sprite = root->get_lisp("supertux-sprite");
00087 if(!sprite) {
00088 std::ostringstream msg;
00089 msg << "'" << filename << "' is not a supertux-sprite file";
00090 throw std::runtime_error(msg.str());
00091 }
00092
00093 std::auto_ptr<SpriteData> data (
00094 new SpriteData(*sprite, FileSystem::dirname(filename)) );
00095 sprites[filename] = data.release();
00096
00097 return sprites[filename];
00098 }
00099
00100