Torque3D Documentation / _generateds / virtualMountSystem.cpp

virtualMountSystem.cpp

Engine/source/core/virtualMountSystem.cpp

More...

Namespaces:

namespace
namespace

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "core/virtualMountSystem.h"
 26
 27#include "console/console.h"
 28#include "core/tAlgorithm.h"
 29
 30namespace Torque
 31{
 32namespace FS
 33{
 34
 35bool gVMSVerboseLog = false;
 36
 37bool VirtualMountSystem::mount(String root, FileSystemRef fs)
 38{
 39   bool ok = Parent::mount(root,fs);
 40   if (!ok)
 41      return false;
 42
 43   root = String::ToLower(root);
 44
 45   mRootMap[root].push_back(fs);
 46
 47//    PathFSMap* rootDict = NULL;
 48//    if (!mMountMap.tryGetValue(root, rootDict))
 49//    {
 50//       rootDict = new PathFSMap();
 51//       mMountMap[root] = rootDict;
 52//    }
 53// 
 54//    U32 start = Platform::getRealMilliseconds();
 55// 
 56//    // get the paths from the fs and add them to the rootDict
 57//    Vector<String> paths;
 58// 
 59//    // we'll use the mount system's findByPattern function to build the path list.
 60//    // but, we want to override its default behavior so that it searches only the desired fs.
 61//    _setFindByPatternOverrideFS(fs);
 62// 
 63//    Torque::Path basePath;
 64//    // we use an empty root so that the resulting filenames don't have the root filename in them.  
 65//    // we don't want to include the root in the dict has entries.  we can omit the root because we have 
 66//    // specified an override FS; the search would fail otherwise.
 67//    //basePath.setRoot(root); 
 68//    basePath.setRoot("");
 69//    basePath.setPath("/");
 70//    mUseParentFind = true;
 71//    if (findByPattern(basePath, "*.*", true, paths, true) == -1)
 72//    {
 73//       // this is probably a problem
 74//       _log("Unable to get paths from filesystem for virtual mount");
 75//       _setFindByPatternOverrideFS(NULL);
 76//       mUseParentFind = false;
 77//       return false;
 78//    }
 79// 
 80//    _setFindByPatternOverrideFS(NULL);
 81//    mUseParentFind = false;
 82// 
 83//    for (S32 i = 0; i < paths.size(); ++i)
 84//    {
 85//       String path = String::ToLower(paths[i]);
 86// 
 87//       // is it a directory? if so remove dir prefix
 88//       String dirPrefix = "DIR:";
 89//       String::SizeType dIdx = path.find(dirPrefix, 0, String::NoCase);
 90//       if (dIdx == 0)
 91//          path = path.substr(dirPrefix.length());
 92//       // omit leading /
 93//       if (path[(String::SizeType)0] == '/')
 94//          path = path.substr(1);
 95// 
 96//       // warn about duplicate files (not directories)
 97//       // JMQ: disabled this, it false alarms at startup because the mount doc always mounts the 
 98//       // root before other processing mounts.  still, would be useful, maybe change the mount doc to 
 99//       // not mount root?
100//       if (dIdx != 0 && (*rootDict)[path].size() > 0)
101//          _log(String::ToString("Duplicate file path detected, first volume containing file will be used: %s", path.c_str()));
102//       
103//       (*rootDict)[path].push_back(fs);
104//    }
105// 
106//    if (gVMSVerboseLog)
107//       _log(String::ToString("Indexed virtual file system in %ums", Platform::getRealMilliseconds() - start));
108
109   return true;
110}
111
112bool VirtualMountSystem::mount(String root, const Path &path)
113{
114   //AssertFatal(false, "This function not supported in virtual mount system");
115   return Parent::mount(root, path);
116}
117
118FileSystemRef VirtualMountSystem::unmount(String root)
119{
120   FileSystemRef ret = Parent::unmount(root);
121
122   mRootMap.erase(root);
123
124   // clear all filesystem lists for root.
125//    PathFSMap* rootDict = NULL;
126//    root = String::ToLower(root);
127//    if (!mMountMap.tryGetValue(root, rootDict))
128//       return ret;
129// 
130//    // buh bye
131//    mMountMap.erase(root);
132//    delete rootDict;
133
134   return ret;
135}
136
137bool VirtualMountSystem::unmount(FileSystemRef fs)
138{
139   bool unmounted = Parent::unmount(fs);
140   if (!unmounted)
141      return false;
142
143   for(PathFSMap::Iterator ritr = mRootMap.begin();ritr != mRootMap.end();++ritr)
144   {
145      RootToFSVec &vec = (*ritr).value;
146      for (S32 i = vec.size() - 1;i >= 0;i--)
147      {
148         if (vec[i].getPointer() == fs.getPointer())
149            vec.erase(i);
150      }
151   }
152   
153   // this is a linear time operation, because we have to search every path in all roots 
154   // to remove references to the fs.
155   // contant time operation can be achieved be using the unmount(string) version, which unmounts all 
156   // filesystems for a given root and so doesn't need to do any searching.
157//    U32 start = Platform::getRealMilliseconds();
158//    for (RootToPathFSMap::Iterator riter = mMountMap.begin();
159//       riter != mMountMap.end();
160//       ++riter)
161//    {
162//       PathFSMap* rootDict = (*riter).value;
163//       for (PathFSMap::Iterator piter = rootDict->begin();
164//          piter != rootDict->end();
165//          ++piter)
166//       {
167//          Vector<FileSystemRef>& plist = (*piter).value;
168//          for (S32 i = plist.size() - 1;
169//             i >= 0;
170//             i--)
171//          {
172//             if (plist[i].getPointer() == fs.getPointer())
173//                plist.erase(i);
174//          }
175//       }
176//    }
177// 
178//    if (gVMSVerboseLog)
179//       _log(String::ToString("Unmounted virtual file system in %ums", Platform::getRealMilliseconds() - start));
180
181   return true;
182}
183
184S32 VirtualMountSystem::findByPattern( const Path &inBasePath, const String &inFilePattern, bool inRecursive, Vector<String> &outList, bool includeDirs/* =false */, bool multiMatch /* = true */ )
185{
186   if (mUseParentFind)
187      // use parent version
188      return Parent::findByPattern(inBasePath, inFilePattern, inRecursive, outList, includeDirs, multiMatch);
189
190   // don't want to re-enter this version
191   mUseParentFind = true;
192
193   // kind of cheesy, just call find by pattern on each File system mounted on the root
194   for (Vector<MountFS>::const_iterator itr = mMountList.begin(); itr != mMountList.end(); itr++)
195   {
196      if (itr->root.equal( inBasePath.getRoot(), String::NoCase ) )
197      {
198         FileSystemRef fsref = itr->fileSystem;
199         _setFindByPatternOverrideFS(fsref);
200         Parent::findByPattern(inBasePath, inFilePattern, inRecursive, outList, includeDirs, multiMatch);
201         _setFindByPatternOverrideFS(NULL);
202      }
203   }
204
205   mUseParentFind = false;
206
207   return outList.size();
208}
209
210bool VirtualMountSystem::createPath(const Path& path)
211{
212   bool ret = Parent::createPath(path);
213
214//    if (ret)
215//    {
216//       // make sure the filesystem that owns the path has the path elements
217//       // in its search table (so that we can open the file, if it is new)
218//       String root = String::ToLower(path.getRoot());
219//       FileSystemRef fsRef = getFileSystem(path);
220// 
221//       PathFSMap* rootDict = mMountMap[root];
222//       if (rootDict)
223//       {
224//          // add all directories in the path
225//          // add the filename
226// 
227//          // Start from the top and work our way down
228//          Path sub,dir;
229//          dir.setPath("");
230//          for (U32 i = 0; i < path.getDirectoryCount(); i++)
231//          {
232//             sub.setPath(path.getDirectory(i));
233//             dir.appendPath(sub);
234// 
235//             Vector<FileSystemRef>& fsList = (*rootDict)[String::ToLower(dir.getPath())];
236//             Vector<FileSystemRef>::iterator iter = ::find(fsList.begin(), fsList.end(), fsRef);
237// 
238//             if (iter == fsList.end())
239//                fsList.push_back(fsRef);
240//          }
241// 
242//          // add full file path
243//          Vector<FileSystemRef>& fsList = (*rootDict)[String::ToLower(path.getFullPath(false))];
244//          Vector<FileSystemRef>::iterator iter = ::find(fsList.begin(), fsList.end(), fsRef);
245//          
246//          if (iter == fsList.end())
247//             fsList.push_back(fsRef);
248//       }
249//    }
250
251   return ret;
252}
253
254void VirtualMountSystem::_log(const String& msg)
255{
256   String newMsg = "VirtualMountSystem: " + msg;
257   Con::warnf("%s", newMsg.c_str());
258}
259
260FileSystemRef VirtualMountSystem::_removeMountFromList(String root)
261{
262   return Parent::_removeMountFromList(root);
263}
264
265FileSystemRef VirtualMountSystem::_getFileSystemFromList(const Path& fullpath) const 
266{
267   String root = String::ToLower(fullpath.getRoot());
268   String path = fullpath.getFullPathWithoutRoot();
269   // eat leading slash
270   if (path[(String::SizeType)0] == '/')
271      path = path.substr(1);
272   // lowercase it
273   path = String::ToLower(path);
274
275   // find the dictionary for root
276//    PathFSMap* rootDict = NULL;
277//    if (!mMountMap.tryGetValue(root, rootDict))
278//       return NULL;
279// 
280//    // see if we have a FS list for this path
281//    Vector<FileSystemRef>& fsList = (*rootDict)[path];
282   
283   RootToFSVec fsList;
284   if(! mRootMap.tryGetValue(root, fsList))
285      return NULL;
286   
287   if (fsList.size() == 0)
288   {
289      // no exact match for path, defer to parent
290      return Parent::_getFileSystemFromList(fullpath);
291   }
292   else
293   {
294      // find the right file system
295      if(fsList.size() == 1)
296         return fsList[0];
297
298      // Go in reverse order to pick up the last matching virtual path
299      for(S32 i = fsList.size()-1; i >= 0 ; --i)
300      {
301         FileNodeRef fn = fsList[i]->resolve(path);
302         if(fn != NULL)
303            return fsList[i];
304      }
305
306      return fsList[0];      
307   }
308}
309
310} //namespace FS
311} //namespace Torque
312