llrender and lldir merge. Removed duplicate assets from skins. cleaned up skin textures.xml files to only include changes from default.

This commit is contained in:
Shyotl
2016-04-11 02:51:08 -05:00
parent d40256fb31
commit be5d2f20bc
1280 changed files with 2354 additions and 10692 deletions

View File

@@ -71,8 +71,15 @@ LLDir_Linux gDirUtil;
LLDir *gDirUtilp = (LLDir *)&gDirUtil;
/// Values for findSkinnedFilenames(subdir) parameter
const char
*LLDir::XUI = "xui",
*LLDir::TEXTURES = "textures",
*LLDir::SKINBASE = "";
static const char* const empty = "";
std::string LLDir::sDumpDir = "";
LLDir::LLDir()
: mAppName(""),
mExecutablePathAndName(""),
@@ -85,7 +92,9 @@ LLDir::LLDir()
mOSCacheDir(""),
mCAFile(""),
mTempDir(""),
mDirDelimiter("/") // fallback to forward slash if not overridden
mDirDelimiter("/"), // fallback to forward slash if not overridden
mLanguage("en"),
mUserName("undefined")
{
}
@@ -97,7 +106,11 @@ std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname)
{
//Returns a vector of fullpath filenames.
#if LL_WINDOWS
boost::filesystem::path p (utf8str_to_utf16str(dirname).c_str());
#else
boost::filesystem::path p (dirname);
#endif
std::vector<std::string> v;
if (exists(p))
@@ -188,19 +201,33 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
U32 LLDir::deleteDirAndContents(const std::string& dir_name)
{
//Removes the directory and its contents. Returns number of files removed.
// Singu Note: boost::filesystem throws exceptions
S32 res = 0;
U32 num_deleted = 0;
try
try
{
res = boost::filesystem::remove_all(dir_name);
#if LL_WINDOWS
boost::filesystem::path dir_path(utf8str_to_utf16str(dir_name).c_str());
#else
boost::filesystem::path dir_path(dir_name);
#endif
if (boost::filesystem::exists (dir_path))
{
if (!boost::filesystem::is_empty (dir_path))
{ // Directory has content
num_deleted = boost::filesystem::remove_all (dir_path);
}
else
{ // Directory is empty
boost::filesystem::remove (dir_path);
}
}
}
catch(const boost::filesystem::filesystem_error& e)
{
LL_WARNS() << "boost::filesystem::remove_all(\"" + dir_name + "\") failed: '" + e.code().message() + "'" << LL_ENDL;
}
return res;
catch (boost::filesystem::filesystem_error &er)
{
LL_WARNS() << "Failed to delete " << dir_name << " with error " << er.code().message() << LL_ENDL;
}
return num_deleted;
}
const std::string LLDir::findFile(const std::string &filename,
@@ -346,6 +373,12 @@ const std::string LLDir::getCacheDir(bool get_default) const
}
}
#if (defined(_WIN64) || defined(__amd64__) || defined(__x86_64__))
#define OS_CACHE_DIR "SingularityViewer64"
#else
#define OS_CACHE_DIR "Obsidian"
#endif
// Return the default cache directory
std::string LLDir::buildSLOSCacheDir() const
{
@@ -363,11 +396,7 @@ std::string LLDir::buildSLOSCacheDir() const
}
else
{
#if defined(_WIN64)
res = add(getOSCacheDir(), "SingularityViewer64");
#else
res = add(getOSCacheDir(), "SingularityViewer");
#endif
res = add(getOSCacheDir(), OS_CACHE_DIR);
}
return res;
}
@@ -390,20 +419,26 @@ const std::string &LLDir::getDirDelimiter() const
return mDirDelimiter;
}
const std::string& LLDir::getDefaultSkinDir() const
{
return mDefaultSkinDir;
}
const std::string &LLDir::getSkinDir() const
{
return mSkinDir;
}
const std::string& LLDir::getUserDefaultSkinDir() const
{
return mUserDefaultSkinDir;
}
const std::string &LLDir::getUserSkinDir() const
{
return mUserSkinDir;
}
const std::string& LLDir::getDefaultSkinDir() const
{
return mDefaultSkinDir;
}
const std::string LLDir::getSkinBaseDir() const
{
@@ -415,6 +450,11 @@ const std::string &LLDir::getLLPluginDir() const
return mLLPluginDir;
}
const std::string &LLDir::getUserName() const
{
return mUserName;
}
static std::string ELLPathToString(ELLPath location)
{
typedef std::map<ELLPath, const char*> ELLPathMap;
@@ -602,7 +642,7 @@ std::string LLDir::getBaseFileName(const std::string& filepath, bool strip_exten
std::string LLDir::getDirName(const std::string& filepath) const
{
std::size_t offset = filepath.find_last_of(getDirDelimiter());
S32 len = (offset == std::string::npos) ? 0 : offset;
size_t len = (offset == std::string::npos) ? 0 : offset;
std::string dirname = filepath.substr(0, len);
return dirname;
}
@@ -618,31 +658,207 @@ std::string LLDir::getExtension(const std::string& filepath) const
return exten;
}
std::string LLDir::findSkinnedFilename(const std::string &filename) const
std::string LLDir::findSkinnedFilenameBaseLang(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint) const
{
return findSkinnedFilename("", "", filename);
// This implementation is basically just as described in the declaration comments.
std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint));
if (found.empty())
{
return "";
}
return found.front();
}
std::string LLDir::findSkinnedFilename(const std::string &subdir, const std::string &filename) const
std::string LLDir::findSkinnedFilename(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint) const
{
return findSkinnedFilename("", subdir, filename);
// This implementation is basically just as described in the declaration comments.
std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint));
if (found.empty())
{
return "";
}
return found.back();
}
std::string LLDir::findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const
// This method exists because the two code paths for
// findSkinnedFilenames(ALL_SKINS) and findSkinnedFilenames(CURRENT_SKIN) must
// generate the list of candidate pathnames in identical ways. The only
// difference is in the body of the inner loop.
template <typename FUNCTION>
void LLDir::walkSearchSkinDirs(const std::string& subdir,
const std::vector<std::string>& subsubdirs,
const std::string& filename,
const FUNCTION& function) const
{
// generate subdirectory path fragment, e.g. "/foo/bar", "/foo", ""
std::string subdirs = ((subdir1.empty() ? "" : mDirDelimiter) + subdir1)
+ ((subdir2.empty() ? "" : mDirDelimiter) + subdir2);
BOOST_FOREACH(std::string skindir, mSearchSkinDirs)
{
std::string subdir_path(add(skindir, subdir));
BOOST_FOREACH(std::string subsubdir, subsubdirs)
{
std::string full_path(add(add(subdir_path, subsubdir), filename));
if (fileExists(full_path))
{
function(subsubdir, full_path);
}
}
}
}
std::vector<std::string> search_paths;
search_paths.push_back(getUserSkinDir() + subdirs); // first look in user skin override
search_paths.push_back(getSkinDir() + subdirs); // then in current skin
search_paths.push_back(getDefaultSkinDir() + subdirs); // then default skin
search_paths.push_back(getCacheDir() + subdirs); // and last in preload directory
// ridiculous little helper function that should go away when we can use lambda
inline void push_back(std::vector<std::string>& vector, const std::string& value)
{
vector.push_back(value);
}
std::string found_file = findFile(filename, search_paths);
return found_file;
typedef std::map<std::string, std::string> StringMap;
// ridiculous little helper function that should go away when we can use lambda
inline void store_in_map(StringMap& map, const std::string& key, const std::string& value)
{
map[key] = value;
}
std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,
const std::string& filename,
ESkinConstraint constraint) const
{
// Recognize subdirs that have no localization.
static const std::set<std::string> sUnlocalized = list_of
("") // top-level directory not localized
("textures") // textures not localized
;
LL_DEBUGS("LLDir") << "subdir '" << subdir << "', filename '" << filename
<< "', constraint "
<< ((constraint == CURRENT_SKIN)? "CURRENT_SKIN" : "ALL_SKINS")
<< LL_ENDL;
// Cache the default language directory for each subdir we've encountered.
// A cache entry whose value is the empty string means "not localized,
// don't bother checking again."
static StringMap sLocalized;
// Check whether we've already discovered if this subdir is localized.
StringMap::const_iterator found = sLocalized.find(subdir);
if (found == sLocalized.end())
{
// We have not yet determined that. Is it one of the subdirs "known"
// to be unlocalized?
if (sUnlocalized.find(subdir) != sUnlocalized.end())
{
// This subdir is known to be unlocalized. Remember that.
found = sLocalized.insert(StringMap::value_type(subdir, "")).first;
}
else
{
// We do not recognize this subdir. Investigate.
std::string subdir_path(add(getDefaultSkinDir(), subdir));
if (fileExists(add(subdir_path, "en")))
{
// defaultSkinDir/subdir contains subdir "en". That's our
// default language; this subdir is localized.
found = sLocalized.insert(StringMap::value_type(subdir, "en")).first;
}
else if (fileExists(add(subdir_path, "en-us")))
{
// defaultSkinDir/subdir contains subdir "en-us" but not "en".
// Set as default language; this subdir is localized.
found = sLocalized.insert(StringMap::value_type(subdir, "en-us")).first;
}
else
{
// defaultSkinDir/subdir contains neither "en" nor "en-us".
// Assume it's not localized. Remember that assumption.
found = sLocalized.insert(StringMap::value_type(subdir, "")).first;
}
}
}
// Every code path above should have resulted in 'found' becoming a valid
// iterator to an entry in sLocalized.
llassert(found != sLocalized.end());
// Now -- is this subdir localized, or not? The answer determines what
// subdirectories we check (under subdir) for the requested filename.
std::vector<std::string> subsubdirs;
if (found->second.empty())
{
// subdir is not localized. filename should be located directly within it.
subsubdirs.push_back("");
}
else
{
// subdir is localized, and found->second is the default language
// directory within it. Check both the default language and the
// current language -- if it differs from the default, of course.
subsubdirs.push_back(found->second);
if (mLanguage != found->second)
{
subsubdirs.push_back(mLanguage);
}
}
// Build results vector.
std::vector<std::string> results;
// The process we use depends on 'constraint'.
if (constraint != CURRENT_SKIN) // meaning ALL_SKINS
{
// ALL_SKINS is simpler: just return every pathname generated by
// walkSearchSkinDirs(). Tricky bit: walkSearchSkinDirs() passes its
// FUNCTION the subsubdir as well as the full pathname. We just want
// the full pathname.
walkSearchSkinDirs(subdir, subsubdirs, filename,
boost::bind(push_back, boost::ref(results), _2));
}
else // CURRENT_SKIN
{
// CURRENT_SKIN turns out to be a bit of a misnomer because we might
// still return files from two different skins. In any case, this
// value of 'constraint' means we will return at most two paths: one
// for the default language, one for the current language (supposing
// those differ).
// It is important to allow a user to override only the localization
// for a particular file, for all viewer installs, without also
// overriding the default-language file.
// It is important to allow a user to override only the default-
// language file, for all viewer installs, without also overriding the
// applicable localization of that file.
// Therefore, treat the default language and the current language as
// two separate cases. For each, capture the most-specialized file
// that exists.
// Use a map keyed by subsubdir (i.e. language code). This allows us
// to handle the case of a single subsubdirs entry with the same logic
// that handles two. For every real file path generated by
// walkSearchSkinDirs(), update the map entry for its subsubdir.
StringMap path_for;
walkSearchSkinDirs(subdir, subsubdirs, filename,
boost::bind(store_in_map, boost::ref(path_for), _1, _2));
// Now that we have a path for each of the default language and the
// current language, copy them -- in proper order -- into results.
// Don't drive this by walking the map itself: it matters that we
// generate results in the same order as subsubdirs.
BOOST_FOREACH(std::string subsubdir, subsubdirs)
{
StringMap::const_iterator found(path_for.find(subsubdir));
if (found != path_for.end())
{
results.push_back(found->second);
}
}
}
LL_DEBUGS("LLDir") << empty;
const char* comma = "";
BOOST_FOREACH(std::string path, results)
{
LL_CONT << comma << "'" << path << "'";
comma = ", ";
}
LL_CONT << LL_ENDL;
return results;
}
std::string LLDir::getTempFilename() const
@@ -657,7 +873,7 @@ std::string LLDir::getTempFilename() const
}
// static
std::string LLDir::getScrubbedFileName(const std::string uncleanFileName)
std::string LLDir::getScrubbedFileName(const std::string& uncleanFileName)
{
std::string name(uncleanFileName);
std::string illegalChars(getForbiddenFileChars());
@@ -668,8 +884,8 @@ std::string LLDir::getScrubbedFileName(const std::string uncleanFileName)
// replace any illegal file chars with and underscore '_'
for( unsigned int i = 0; i < illegalChars.length(); i++ )
{
int j = -1;
while((j = name.find(illegalChars[i])) > -1)
size_t j = std::string::npos;
while ((j = name.find(illegalChars[i])) != std::string::npos)
{
name[j] = '_';
}
@@ -683,6 +899,19 @@ std::string LLDir::getForbiddenFileChars()
return "\\/:*?\"<>|";
}
// static
std::string LLDir::getGridSpecificDir( const std::string& in, const std::string& grid )
{
std::string ret;
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
ret = in + "@" + gridlower;
}
return ret;
}
void LLDir::setLindenUserDir(const std::string &grid, const std::string &first, const std::string &last)
{
// if both first and last aren't set, assume we're grabbing the cached dir
@@ -692,15 +921,7 @@ void LLDir::setLindenUserDir(const std::string &grid, const std::string &first,
// utterly consistent with our firstname/lastname case.
std::string userlower(first+"_"+last);
LLStringUtil::toLower(userlower);
mLindenUserDir = add(getOSUserAppDir(), userlower);
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
mLindenUserDir += "@";
mLindenUserDir += gridlower;
}
mLindenUserDir = getGridSpecificDir(grid, add(getOSUserAppDir(), userlower));
}
else
{
@@ -737,7 +958,7 @@ void LLDir::makePortable()
initAppDirs(mAppName); // This is kinda lazy, but it's probably the quickest, most uniform way.
}
void LLDir::setChatLogsDir(const std::string &path)
void LLDir::setChatLogsDir( const std::string& path)
{
if (!path.empty() )
{
@@ -749,6 +970,11 @@ void LLDir::setChatLogsDir(const std::string &path)
}
}
void LLDir::updatePerAccountChatLogsDir(const std::string &grid)
{
mPerAccountChatLogsDir = getGridSpecificDir(grid, add(getChatLogsDir(), mUserName));
}
void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string &first, const std::string &last)
{
// if both first and last aren't set, assume we're grabbing the cached dir
@@ -758,14 +984,9 @@ void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string
// utterly consistent with our firstname/lastname case.
std::string userlower(first+"_"+last);
LLStringUtil::toLower(userlower);
mPerAccountChatLogsDir = add(getChatLogsDir(), userlower);
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
mPerAccountChatLogsDir += "@";
mPerAccountChatLogsDir += gridlower;
}
mUserName = userlower;
updatePerAccountChatLogsDir(grid);
}
else
{
@@ -773,21 +994,59 @@ void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string
}
}
void LLDir::setSkinFolder(const std::string &skin_folder)
void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language)
{
mSkinDir = getSkinBaseDir();
append(mSkinDir, skin_folder);
LL_DEBUGS("LLDir") << "Setting skin '" << skin_folder << "', language '" << language << "'"
<< LL_ENDL;
mSkinName = skin_folder;
mLanguage = language;
// user modifications to current skin
// e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle
mUserSkinDir = getOSUserAppDir();
append(mUserSkinDir, "skins_sg1");
append(mUserSkinDir, skin_folder);
// This method is called multiple times during viewer initialization. Each
// time it's called, reset mSearchSkinDirs.
mSearchSkinDirs.clear();
// base skin which is used as fallback for all skinned files
// e.g. c:\program files\secondlife\skins\default
mDefaultSkinDir = getSkinBaseDir();
append(mDefaultSkinDir, "default");
// This is always the most general of the search skin directories.
addSearchSkinDir(mDefaultSkinDir);
mSkinDir = getSkinBaseDir();
append(mSkinDir, skin_folder);
// Next level of generality is a skin installed with the viewer.
addSearchSkinDir(mSkinDir);
// user modifications to skins, current and default
// e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle
mUserSkinDir = getOSUserAppDir();
append(mUserSkinDir, "skins_sg1");
mUserDefaultSkinDir = mUserSkinDir;
append(mUserDefaultSkinDir, "default");
append(mUserSkinDir, skin_folder);
// Next level of generality is user modifications to default skin...
addSearchSkinDir(mUserDefaultSkinDir);
// then user-defined skins.
addSearchSkinDir(mUserSkinDir);
}
void LLDir::addSearchSkinDir(const std::string& skindir)
{
if (std::find(mSearchSkinDirs.begin(), mSearchSkinDirs.end(), skindir) == mSearchSkinDirs.end())
{
LL_DEBUGS("LLDir") << "search skin: '" << skindir << "'" << LL_ENDL;
mSearchSkinDirs.push_back(skindir);
}
}
std::string LLDir::getSkinFolder() const
{
return mSkinName;
}
std::string LLDir::getLanguage() const
{
return mLanguage;
}
bool LLDir::setCacheDir(const std::string &path)