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