1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2011
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // Scorched3D 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.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ////////////////////////////////////////////////////////////////////////////////
20
21 #include <common/OptionsScorched.h>
22 #include <common/Logger.h>
23 #include <engine/ScorchedContext.h>
24 #include <landscapedef/LandscapeTex.h>
25 #include <landscapedef/LandscapeDefn.h>
26 #include <landscapedef/LandscapeDefinitions.h>
27 #include <landscapedef/LandscapeOptions.h>
28 #include <landscapedef/LandscapeInclude.h>
29 #include <net/NetBufferPool.h>
30
OptionsScorched()31 OptionsScorched::OptionsScorched()
32 {
33 }
34
~OptionsScorched()35 OptionsScorched::~OptionsScorched()
36 {
37 }
38
updateLevelOptions(ScorchedContext & context,LandscapeDefinition & defn)39 void OptionsScorched::updateLevelOptions(ScorchedContext &context, LandscapeDefinition &defn)
40 {
41 // Get the current level data
42 LandscapeTex *ltex = context.getLandscapes().getTex(defn.getTex());
43 LandscapeDefn *ldefn = context.getLandscapes().getDefn(defn.getDefn());
44
45 // Get all of the options specified in the current level
46 std::map<std::string, OptionEntry *> values;
47 updateLevelOptions(ltex->texDefn.includes, values);
48 updateLevelOptions(ldefn->texDefn.includes, values);
49
50 // Iterate over the level and current options
51 std::list<OptionEntry *> &levelOptions = getLevelOptions().getOptions();
52 std::list<OptionEntry *> &mainoptions = getMainOptions().getOptions();
53 std::list<OptionEntry *>::iterator levelitor;
54 std::list<OptionEntry *>::iterator mainitor;
55 for (levelitor = levelOptions.begin(), mainitor = mainoptions.begin();
56 levelitor != levelOptions.end() && mainitor != mainoptions.end();
57 ++levelitor, ++mainitor)
58 {
59 OptionEntry *mainEntry = (*mainitor);
60 OptionEntry *levelEntry = (*levelitor);
61
62 // Get the current settings value that is in use
63 OptionEntry *currentEntry = mainEntry;
64 if (levelEntry->isChangedValue()) currentEntry = levelEntry;
65 std::string oldValue = currentEntry->getValueAsString();
66
67 // Reset the level entry
68 levelEntry->setNotChanged();
69
70 // If this level entry has changed set its new value
71 std::map<std::string, OptionEntry *>::iterator findItor =
72 values.find(mainEntry->getName());
73 if (findItor != values.end())
74 {
75 levelEntry->setValueFromString((*findItor).second->getValueAsString());
76 }
77
78 // Find out the new settings value that is in use
79 currentEntry = mainEntry;
80 if (levelEntry->isChangedValue()) currentEntry = levelEntry;
81 std::string newValue = currentEntry->getValueAsString();
82
83 // Log if the value has changed
84 if (0 != strcmp(newValue.c_str(), oldValue.c_str()))
85 {
86 Logger::log(S3D::formatStringBuffer("Level option %s has been changed from %s to %s",
87 mainEntry->getName(),
88 oldValue.c_str(), newValue.c_str()));
89 }
90 }
91 }
92
updateLevelOptions(std::vector<LandscapeInclude * > & options,std::map<std::string,OptionEntry * > & values)93 void OptionsScorched::updateLevelOptions(std::vector<LandscapeInclude *> &options,
94 std::map<std::string, OptionEntry *> &values)
95 {
96 // For each include
97 std::vector<LandscapeInclude *>::iterator itor;
98 for (itor = options.begin();
99 itor != options.end();
100 ++itor)
101 {
102 LandscapeInclude *option = (*itor);
103
104 // For each set of options
105 std::vector<LandscapeOptionsType *>::iterator typeItor;
106 for (typeItor = option->options.begin();
107 typeItor != option->options.end();
108 ++typeItor)
109 {
110 LandscapeOptionsType *optionType = (*typeItor);
111
112 // For each option
113 std::list<OptionEntry *>::iterator srcitor;
114 for (srcitor = optionType->options.getOptions().begin();
115 srcitor != optionType->options.getOptions().end();
116 ++srcitor)
117 {
118 OptionEntry *srcEntry = (*srcitor);
119 if (srcEntry->isChangedValue())
120 {
121 values[srcEntry->getName()] = srcEntry;
122 }
123 }
124 }
125 }
126 }
127
updateChangeSet()128 void OptionsScorched::updateChangeSet()
129 {
130 NetBuffer *defaultBuffer = NetBufferPool::instance()->getFromPool();
131
132 defaultBuffer->reset();
133 mainOptions_.writeToBuffer(*defaultBuffer, true, true);
134 NetBufferReader reader(*defaultBuffer);
135 changedOptions_.readFromBuffer(reader, true, true);
136
137 NetBufferPool::instance()->addToPool(defaultBuffer);
138 }
139
commitChanges()140 bool OptionsScorched::commitChanges()
141 {
142 bool different = false;
143
144 // Compare buffers
145 std::list<OptionEntry *> &options = mainOptions_.getOptions();
146 std::list<OptionEntry *> &otheroptions = changedOptions_.getOptions();
147 std::list<OptionEntry *>::iterator itor;
148 std::list<OptionEntry *>::iterator otheritor;
149 for (itor=options.begin(), otheritor=otheroptions.begin();
150 itor!=options.end() && otheritor!=otheroptions.end();
151 ++itor, ++otheritor)
152 {
153 OptionEntry *entry = *itor;
154 OptionEntry *otherentry = *otheritor;
155
156 DIALOG_ASSERT(0 == strcmp(entry->getName(), otherentry->getName()));
157
158 std::string str = entry->getValueAsString();
159 std::string otherstr = otherentry->getValueAsString();
160 if (str != otherstr)
161 {
162 if (!(entry->getData() & OptionEntry::DataProtected) &&
163 !(otherentry->getData() & OptionEntry::DataProtected))
164 {
165 if (strlen(str.c_str()) < 20 && strlen(otherstr.c_str()) < 20)
166 {
167 Logger::log(S3D::formatStringBuffer("Option %s has been changed from %s to %s",
168 entry->getName(), str.c_str(), otherstr.c_str()));
169 }
170 else
171 {
172 Logger::log(S3D::formatStringBuffer("Option %s has been changed.",
173 entry->getName()));
174 }
175 }
176
177 different = true;
178 entry->setValueFromString(otherentry->getValueAsString());
179 }
180 }
181
182 return different;
183 }
184