1// SuperTux
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include "sprite/sprite_manager.hpp"
18
19#include "sprite/sprite.hpp"
20#include "util/file_system.hpp"
21#include "util/reader_document.hpp"
22#include "util/reader_mapping.hpp"
23#include "util/string_util.hpp"
24
25#include <sstream>
26
27SpriteManager::SpriteManager() :
28 sprites()
29{
30}
31
32SpritePtr
33SpriteManager::create(const std::string& name)
34{
35 Sprites::iterator i = sprites.find(name);
36 SpriteData* data;
37 if (i == sprites.end()) {
38 // try loading the spritefile
39 data = load(name);
40 if (data == nullptr) {
41 std::stringstream msg;
42 msg << "Sprite '" << name << "' not found.";
43 throw std::runtime_error(msg.str());
44 }
45 } else {
46 data = i->second.get();
47 }
48
49 return SpritePtr(new Sprite(*data));
50}
51
52SpriteData*
53SpriteManager::load(const std::string& filename)
54{
55 ReaderDocument doc = [filename](){
56 try {
57 if (StringUtil::has_suffix(filename, ".sprite")) {
58 return ReaderDocument::from_file(filename);
59 } else {
60 std::stringstream text;
61 text << "(supertux-sprite (action "
62 << "(name \"default\") "
63 << "(images \"" << FileSystem::basename(filename) << "\")))";
64 return ReaderDocument::from_stream(text, filename);
65 }
66 } catch(const std::exception& e) {
67 std::ostringstream msg;
68 msg << "Parse error when trying to load sprite '" << filename
69 << "': " << e.what() << "\n";
70 throw std::runtime_error(msg.str());
71 }
72 }();
73
74 auto root = doc.get_root();
75
76 if (root.get_name() != "supertux-sprite") {
77 std::ostringstream msg;
78 msg << "'" << filename << "' is not a supertux-sprite file";
79 throw std::runtime_error(msg.str());
80 } else {
81 auto data = std::make_unique<SpriteData>(root.get_mapping());
82 sprites[filename] = std::move(data);
83
84 return sprites[filename].get();
85 }
86}
87
88/* EOF */
89