1
// $Id: sexpr_file_reader.cpp 2987 2007-08-17 16:25:49Z grumbel $
3
// Pingus - A free Lemmings clone
4
// Copyright (C) 2005 Ingo Ruhnke <grumbel@gmx.de>
6
// This program is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public License
8
// as published by the Free Software Foundation; either version 2
9
// of the License, or (at your option) any later version.
11
// This program is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
// GNU General Public License for more details.
16
// You should have received a copy of the GNU General Public License
17
// along with this program; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
#include "math/vector3f.hpp"
22
#include "math/color.hpp"
23
#include "math/size.hpp"
24
#include "res_descriptor.hpp"
25
#include "resource_modifier.hpp"
26
#include "math/vector2i.hpp"
27
#include "file_reader_impl.hpp"
28
#include "sexpr_file_reader.hpp"
30
class SExprFileReaderImpl: public FileReaderImpl
33
boost::shared_ptr<lisp::Lisp> sexpr;
35
SExprFileReaderImpl(boost::shared_ptr<lisp::Lisp> sexpr_)
38
assert(sexpr->get_type() == lisp::Lisp::TYPE_LIST &&
39
sexpr->get_list_size() >= 1);
41
for(size_t i = 1; i < sexpr->get_list_size(); ++i)
42
{ // iterate over subsections
43
sexpr->get_list_elem(i);
47
~SExprFileReaderImpl()
49
// FIXME: Do we have to free the lisp pointer here or outside of the code?
52
std::string get_name() const
54
return sexpr->get_list_elem(0)->get_symbol();
57
bool read_int (const char* name, int& v) const
59
boost::shared_ptr<lisp::Lisp> item = get_subsection_item(name);
60
if (item && item->get_type() == lisp::Lisp::TYPE_INT)
68
bool read_float (const char* name, float& v) const
70
boost::shared_ptr<lisp::Lisp> item = get_subsection_item(name);
73
if (item->get_type() == lisp::Lisp::TYPE_FLOAT)
75
v = item->get_float();
78
else if (item->get_type() == lisp::Lisp::TYPE_INT)
80
v = (float)item->get_int();
91
bool read_bool (const char* name, bool& v) const
93
boost::shared_ptr<lisp::Lisp> item = get_subsection_item(name);
94
if (item && item->get_type() == lisp::Lisp::TYPE_BOOL)
99
else if (item && item->get_type() == lisp::Lisp::TYPE_INT)
107
bool read_string(const char* name, std::string& v) const
109
boost::shared_ptr<lisp::Lisp> sub = get_subsection(name);
113
for(size_t i = 1; i < sub->get_list_size(); ++i)
115
boost::shared_ptr<lisp::Lisp> item = sub->get_list_elem(i);
116
if (item->get_type() == lisp::Lisp::TYPE_STRING)
118
v += item->get_string();
120
else if (item->get_type() == lisp::Lisp::TYPE_SYMBOL)
122
v += item->get_symbol();
130
bool read_vector(const char* name, Vector3f& v) const
132
boost::shared_ptr<lisp::Lisp> sub = get_subsection(name);
133
if (sub && sub->get_list_size() == 4)
135
v = Vector3f(sub->get_list_elem(1)->get_float(),
136
sub->get_list_elem(2)->get_float(),
137
sub->get_list_elem(3)->get_float());
143
bool read_size(const char* name, Size& v) const
145
boost::shared_ptr<lisp::Lisp> sub = get_subsection(name);
146
if (sub && sub->get_list_size() == 3)
148
v.width = sub->get_list_elem(1)->get_int();
149
v.height = sub->get_list_elem(2)->get_int();
155
bool read_vector2i(const char* name, Vector2i& v) const
157
boost::shared_ptr<lisp::Lisp> sub = get_subsection(name);
158
if (sub && sub->get_list_size() == 3)
160
v.x = sub->get_list_elem(1)->get_int();
161
v.y = sub->get_list_elem(2)->get_int();
167
bool read_color (const char* name, Color& v) const
169
boost::shared_ptr<lisp::Lisp> sub = get_subsection(name);
170
if (sub && sub->get_list_size() == 5)
172
v = Color(int(sub->get_list_elem(1)->get_float() * 255),
173
int(sub->get_list_elem(2)->get_float() * 255),
174
int(sub->get_list_elem(3)->get_float() * 255),
175
int(sub->get_list_elem(4)->get_float() * 255));
181
bool read_desc (const char* name, ResDescriptor& v) const
183
boost::shared_ptr<lisp::Lisp> sub = get_subsection(name);
186
SExprFileReader reader(sub);
187
reader.read_string("image", v.res_name);
188
reader.read_enum("modifier", v.modifier, ResourceModifierNS::rs_from_string);
194
bool read_section(const char* name, FileReader& v) const
196
boost::shared_ptr<lisp::Lisp> cur = get_subsection(name);
199
v = SExprFileReader(cur);
205
std::vector<FileReader> get_sections() const
207
std::vector<FileReader> lst;
208
for(size_t i = 1; i < sexpr->get_list_size(); ++i)
209
{ // iterate over subsections
210
lst.push_back(SExprFileReader(sexpr->get_list_elem(i)));
215
std::vector<std::string> get_section_names() const
217
std::vector<std::string> lst;
219
for(size_t i = 1; i < sexpr->get_list_size(); ++i)
220
{ // iterate over subsections
221
boost::shared_ptr<lisp::Lisp> sub = sexpr->get_list_elem(i);
222
lst.push_back(sub->get_list_elem(0)->get_symbol());
229
boost::shared_ptr<lisp::Lisp> get_subsection_item(const char* name) const
231
boost::shared_ptr<lisp::Lisp> sub = get_subsection(name);
232
if (sub && sub->get_list_size() == 2)
234
return sub->get_list_elem(1);
236
return boost::shared_ptr<lisp::Lisp>();
239
boost::shared_ptr<lisp::Lisp> get_subsection(const char* name) const
241
for(size_t i = 1; i < sexpr->get_list_size(); ++i)
242
{ // iterate over subsections
243
boost::shared_ptr<lisp::Lisp> sub = sexpr->get_list_elem(i);
244
if (strcmp(sub->get_list_elem(0)->get_symbol(), name) == 0)
247
return boost::shared_ptr<lisp::Lisp>();
252
SExprFileReader::SExprFileReader(boost::shared_ptr<lisp::Lisp> lisp)
253
: FileReader(boost::shared_ptr<FileReaderImpl>(new SExprFileReaderImpl(lisp)))