PageRenderTime 5ms CodeModel.GetById 10ms app.highlight 63ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llwldaycycle.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 339 lines | 235 code | 54 blank | 50 comment | 32 complexity | 56662f3c7b6e7ce65382931e8face1ee MD5 | raw file
  1/**
  2 * @file llwldaycycle.cpp
  3 * @brief Implementation for the LLWLDayCycle class.
  4 *
  5 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llwldaycycle.h"
 30#include "llsdserialize.h"
 31#include "llwlparammanager.h"
 32#include "llnotifications.h"
 33
 34#include "llviewerwindow.h"
 35
 36#include <map>
 37
 38LLWLDayCycle::LLWLDayCycle() : mDayRate(120)
 39{
 40}
 41
 42
 43LLWLDayCycle::~LLWLDayCycle()
 44{
 45}
 46
 47void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope)
 48{
 49	lldebugs << "Loading day cycle (day_data.size() = " << day_data.size() << ", scope = " << scope << ")" << llendl;
 50	mTimeMap.clear();
 51
 52	// add each key frame
 53	for(S32 i = 0; i < day_data.size(); ++i)
 54	{
 55		// make sure it's a two array
 56		if(day_data[i].size() != 2)
 57		{
 58			continue;
 59		}
 60		
 61		// check each param key exists in param manager
 62		bool success;
 63		LLWLParamSet pset;
 64		LLWLParamKey frame = LLWLParamKey(day_data[i][1].asString(), scope);
 65		success =
 66			LLWLParamManager::getInstance()->getParamSet(frame, pset);
 67		if(!success)
 68		{
 69			// *HACK: If loading region day cycle, try local sky presets as well.
 70			// Local presets may be referenced by a region day cycle after
 71			// it has been edited but the changes have not been uploaded.
 72			if (scope == LLEnvKey::SCOPE_REGION)
 73			{
 74				frame.scope = LLEnvKey::SCOPE_LOCAL;
 75				success = LLWLParamManager::getInstance()->getParamSet(frame, pset);
 76			}
 77
 78			if (!success)
 79			{
 80				// alert the user
 81				LLSD args;
 82				args["SKY"] = day_data[i][1].asString();
 83				LLNotifications::instance().add("WLMissingSky", args, LLSD());
 84				continue;
 85			}
 86		}
 87		
 88		// then add the keyframe
 89		addKeyframe((F32)day_data[i][0].asReal(), frame);
 90	}
 91}
 92
 93void LLWLDayCycle::loadDayCycleFromFile(const std::string & fileName)
 94{
 95	loadDayCycle(loadCycleDataFromFile(fileName), LLWLParamKey::SCOPE_LOCAL);
 96}
 97
 98/*static*/ LLSD LLWLDayCycle::loadCycleDataFromFile(const std::string & fileName)
 99{
100	// *FIX: Cannot load user day cycles.
101	std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, 
102		"windlight/days", fileName));
103
104	return loadDayCycleFromPath(pathName);
105}
106
107// static
108LLSD LLWLDayCycle::loadDayCycleFromPath(const std::string& file_path)
109{
110	LL_INFOS("Windlight") << "Loading DayCycle settings from " << file_path << LL_ENDL;
111	
112	llifstream day_cycle_xml(file_path);
113	if (day_cycle_xml.is_open())
114	{
115		// load and parse it
116		LLSD day_data(LLSD::emptyArray());
117		LLPointer<LLSDParser> parser = new LLSDXMLParser();
118		parser->parse(day_cycle_xml, day_data, LLSDSerialize::SIZE_UNLIMITED);
119		day_cycle_xml.close();
120		return day_data;
121	}
122	else
123	{
124		return LLSD();
125	}
126}
127
128void LLWLDayCycle::saveDayCycle(const std::string & fileName)
129{
130	std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", fileName));
131	//llinfos << "Saving WindLight settings to " << pathName << llendl;
132
133	save(pathName);
134}
135
136void LLWLDayCycle::save(const std::string& file_path)
137{
138	LLSD day_data = asLLSD();
139
140	llofstream day_cycle_xml(file_path);
141	LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
142	formatter->format(day_data, day_cycle_xml, LLSDFormatter::OPTIONS_PRETTY);
143	day_cycle_xml.close();
144}
145
146LLSD LLWLDayCycle::asLLSD()
147{
148	LLSD day_data(LLSD::emptyArray());
149	for(std::map<F32, LLWLParamKey>::const_iterator mIt = mTimeMap.begin(); mIt != mTimeMap.end(); ++mIt) 
150	{
151		LLSD key(LLSD::emptyArray());
152		key.append(mIt->first);
153		key.append(mIt->second.name);
154		day_data.append(key);
155	}
156
157	lldebugs << "Dumping day cycle (" << mTimeMap.size() << ") to LLSD: " << day_data << llendl;
158	return day_data;
159}
160
161bool LLWLDayCycle::getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const
162{
163	bool result = true;
164	LLWLParamManager& wl_mgr = LLWLParamManager::instance();
165
166	refs.clear();
167	for (std::map<F32, LLWLParamKey>::const_iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter)
168	{
169		const LLWLParamKey& key = iter->second;
170		if (!wl_mgr.getParamSet(key, refs[key]))
171		{
172			llwarns << "Cannot find sky [" << key.name << "] referenced by a day cycle" << llendl;
173			result = false;
174		}
175	}
176
177	return result;
178}
179
180bool LLWLDayCycle::getSkyMap(LLSD& sky_map) const
181{
182	std::map<LLWLParamKey, LLWLParamSet> refs;
183
184	if (!getSkyRefs(refs))
185	{
186		return false;
187	}
188
189	sky_map = LLWLParamManager::createSkyMap(refs);
190	return true;
191}
192
193void LLWLDayCycle::clearKeyframes()
194{
195	lldebugs << "Clearing key frames" << llendl;
196	mTimeMap.clear();
197}
198
199
200bool LLWLDayCycle::addKeyframe(F32 newTime, LLWLParamKey frame)
201{
202	// no adding negative time
203	if(newTime < 0) 
204	{
205		newTime = 0;
206	}
207
208	// if time not being used, add it and return true
209	if(mTimeMap.find(newTime) == mTimeMap.end()) 
210	{
211		mTimeMap.insert(std::pair<F32, LLWLParamKey>(newTime, frame));
212		lldebugs << "Adding key frame (" << newTime << ", " << frame.toLLSD() << ")" << llendl;
213		return true;
214	}
215
216	// otherwise, don't add, and return error
217	llwarns << "Error adding key frame (" << newTime << ", " << frame.toLLSD() << ")" << llendl;
218	return false;
219}
220
221bool LLWLDayCycle::changeKeyframeTime(F32 oldTime, F32 newTime)
222{
223	lldebugs << "Changing key frame time (" << oldTime << " => " << newTime << ")" << llendl;
224
225	// just remove and add back
226	LLWLParamKey frame = mTimeMap[oldTime];
227
228	bool stat = removeKeyframe(oldTime);
229	if(stat == false) 
230	{
231		lldebugs << "Failed to change key frame time (" << oldTime << " => " << newTime << ")" << llendl;
232		return stat;
233	}
234
235	return addKeyframe(newTime, frame);
236}
237
238bool LLWLDayCycle::changeKeyframeParam(F32 time, LLWLParamKey key)
239{
240	lldebugs << "Changing key frame param (" << time << ", " << key.toLLSD() << ")" << llendl;
241
242	// just remove and add back
243	// make sure param exists
244	LLWLParamSet tmp;
245	bool stat = LLWLParamManager::getInstance()->getParamSet(key, tmp);
246	if(stat == false) 
247	{
248		lldebugs << "Failed to change key frame param (" << time << ", " << key.toLLSD() << ")" << llendl;
249		return stat;
250	}
251
252	mTimeMap[time] = key;
253	return true;
254}
255
256
257bool LLWLDayCycle::removeKeyframe(F32 time)
258{
259	lldebugs << "Removing key frame (" << time << ")" << llendl;
260
261	// look for the time.  If there, erase it
262	std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
263	if(mIt != mTimeMap.end()) 
264	{
265		mTimeMap.erase(mIt);
266		return true;
267	}
268
269	return false;
270}
271
272bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) const
273{
274	// scroll through till we find the correct value in the map
275	std::map<F32, LLWLParamKey>::const_iterator mIt = mTimeMap.begin();
276	for(; mIt != mTimeMap.end(); ++mIt) 
277	{
278		if(frame == mIt->second) 
279		{
280			key_time = mIt->first;
281			return true;
282		}
283	}
284
285	return false;
286}
287
288bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param)
289{
290	// just scroll on through till you find it
291	std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
292	if(mIt != mTimeMap.end())
293	{
294		return LLWLParamManager::getInstance()->getParamSet(mIt->second, param);
295	}
296
297	// return error if not found
298	lldebugs << "Key " << time << " not found" << llendl;
299	return false;
300}
301
302bool LLWLDayCycle::getKeyedParamName(F32 time, std::string & name)
303{
304	// just scroll on through till you find it
305	std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
306	if(mIt != mTimeMap.end()) 
307	{
308		name = mTimeMap[time].name;
309		return true;
310	}
311
312	// return error if not found
313	lldebugs << "Key " << time << " not found" << llendl;
314	return false;
315}
316
317bool LLWLDayCycle::hasReferencesTo(const LLWLParamKey& keyframe) const
318{
319	F32 dummy;
320	return getKeytime(keyframe, dummy);
321}
322
323void LLWLDayCycle::removeReferencesTo(const LLWLParamKey& keyframe)
324{
325	lldebugs << "Removing references to key frame " << keyframe.toLLSD() << llendl;
326	F32 keytime;
327	bool might_exist;
328	do 
329	{
330		// look for it
331		might_exist = getKeytime(keyframe, keytime);
332		if(!might_exist)
333		{
334			return;
335		}
336		might_exist = removeKeyframe(keytime);
337
338	} while(might_exist); // might be another one
339}