From d31ed83b54383fbb669297e094c3fc66a740305f Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sat, 19 Aug 2017 03:43:31 -0400 Subject: [PATCH 01/12] Preliminary asset reloading --- apps/opencs/model/doc/document.cpp | 4 +-- apps/opencs/model/doc/document.hpp | 6 ++-- apps/opencs/model/doc/documentmanager.cpp | 2 +- apps/opencs/model/doc/documentmanager.hpp | 4 +-- apps/opencs/model/prefs/state.cpp | 1 + apps/opencs/model/world/data.cpp | 33 +++++++++++++++++++- apps/opencs/model/world/data.hpp | 6 ++-- apps/opencs/model/world/resources.cpp | 8 +++++ apps/opencs/model/world/resources.hpp | 2 ++ apps/opencs/model/world/resourcesmanager.cpp | 19 +++++++++-- apps/opencs/model/world/resourcesmanager.hpp | 8 +++-- apps/opencs/model/world/resourcetable.cpp | 10 ++++++ apps/opencs/model/world/resourcetable.hpp | 7 ++++- apps/opencs/view/doc/view.cpp | 8 +++++ components/vfs/archive.hpp | 3 ++ components/vfs/filesystemarchive.cpp | 6 ++++ components/vfs/filesystemarchive.hpp | 2 ++ components/vfs/manager.cpp | 8 +++++ components/vfs/manager.hpp | 3 ++ 19 files changed, 123 insertions(+), 17 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index ef984c0ca..a7809f3e3 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -269,11 +269,11 @@ void CSMDoc::Document::createBase() } } -CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration, +CSMDoc::Document::Document (VFS::Manager* vfs, const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, bool new_, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, const Fallback::Map* fallback, - ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager, + ToUTF8::FromType encoding, CSMWorld::ResourcesManager& resourcesManager, const std::vector& blacklistedScripts) : mVFS(vfs), mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager, fallback, resDir), mTools (*this, encoding), diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 030a0174e..ad0201407 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -59,7 +59,7 @@ namespace CSMDoc private: - const VFS::Manager* mVFS; + VFS::Manager* mVFS; boost::filesystem::path mSavePath; std::vector mContentFiles; bool mNew; @@ -102,11 +102,11 @@ namespace CSMDoc public: - Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration, + Document (VFS::Manager* vfs, const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, bool new_, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, const Fallback::Map* fallback, - ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager, + ToUTF8::FromType encoding, CSMWorld::ResourcesManager& resourcesManager, const std::vector& blacklistedScripts); ~Document(); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 098d7bad5..11378cab4 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -127,7 +127,7 @@ void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std:: removeDocument (document); } -void CSMDoc::DocumentManager::setVFS(const VFS::Manager *vfs) +void CSMDoc::DocumentManager::setVFS(VFS::Manager *vfs) { mResourcesManager.setVFS(vfs); mVFS = vfs; diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index ed8e327d7..771afe8e5 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -41,7 +41,7 @@ namespace CSMDoc ToUTF8::FromType mEncoding; CSMWorld::ResourcesManager mResourcesManager; std::vector mBlacklistedScripts; - const VFS::Manager* mVFS; + VFS::Manager* mVFS; DocumentManager (const DocumentManager&); DocumentManager& operator= (const DocumentManager&); @@ -74,7 +74,7 @@ namespace CSMDoc void setBlacklistedScripts (const std::vector& scriptIds); - void setVFS(const VFS::Manager* vfs); + void setVFS(VFS::Manager* vfs); bool isEmpty(); diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index c87e283a8..5c0b2e282 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -259,6 +259,7 @@ void CSMPrefs::State::declare() declareShortcut ("document-character-topicinfos", "Open Topic Info List", QKeySequence()); declareShortcut ("document-character-journalinfos", "Open Journal Info List", QKeySequence()); declareShortcut ("document-character-bodyparts", "Open Body Part List", QKeySequence()); + declareShortcut ("document-assets-reload", "Reload Assets", QKeySequence(Qt::Key_F5)); declareShortcut ("document-assets-sounds", "Open Sound Asset List", QKeySequence()); declareShortcut ("document-assets-soundgens", "Open Sound Generator List", QKeySequence()); declareShortcut ("document-assets-meshes", "Open Mesh Asset List", QKeySequence()); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index ee9e4329c..8c25faaa5 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -11,6 +11,7 @@ #include #include +#include #include "idtable.hpp" #include "idtree.hpp" @@ -61,7 +62,7 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec return number; } -CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir) +CSMWorld::Data::Data (ToUTF8::FromType encoding, ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir) : mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), mResourcesManager (resourcesManager), mFallbackMap(fallback), mReader (0), mDialogue (0), mReaderIndex(1), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS())) @@ -1215,6 +1216,36 @@ std::vector CSMWorld::Data::getIds (bool listDeleted) const return ids; } +void CSMWorld::Data::assetsChanged() +{ + VFS::Manager* vfs = mResourcesManager.getVFS(); + vfs->rebuildIndex(); + + ResourceTable* meshTable = static_cast(getTableModel(UniversalId::Type_Meshes)); + ResourceTable* iconTable = static_cast(getTableModel(UniversalId::Type_Icons)); + ResourceTable* musicTable = static_cast(getTableModel(UniversalId::Type_Musics)); + ResourceTable* soundResTable = static_cast(getTableModel(UniversalId::Type_SoundsRes)); + ResourceTable* texTable = static_cast(getTableModel(UniversalId::Type_Textures)); + ResourceTable* vidTable = static_cast(getTableModel(UniversalId::Type_Videos)); + + meshTable->beginReset(); + iconTable->beginReset(); + musicTable->beginReset(); + soundResTable->beginReset(); + texTable->beginReset(); + vidTable->beginReset(); + + // Trigger recreation + mResourcesManager.recreateResources(); + + meshTable->endReset(); + iconTable->endReset(); + musicTable->endReset(); + soundResTable->endReset(); + texTable->endReset(); + vidTable->endReset(); +} + void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { if (topLeft.column()<=0) diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index f96003e44..8bc1c4271 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -108,7 +108,7 @@ namespace CSMWorld RefCollection mRefs; IdCollection mFilters; Collection mMetaData; - const ResourcesManager& mResourcesManager; + ResourcesManager& mResourcesManager; const Fallback::Map* mFallbackMap; std::vector mModels; std::map mModelIndex; @@ -140,7 +140,7 @@ namespace CSMWorld public: - Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir); + Data (ToUTF8::FromType encoding, ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir); virtual ~Data(); @@ -306,6 +306,8 @@ namespace CSMWorld private slots: + void assetsChanged(); + void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void rowsChanged (const QModelIndex& parent, int start, int end); diff --git a/apps/opencs/model/world/resources.cpp b/apps/opencs/model/world/resources.cpp index 5fe9194d7..5bf0267bb 100644 --- a/apps/opencs/model/world/resources.cpp +++ b/apps/opencs/model/world/resources.cpp @@ -12,6 +12,14 @@ CSMWorld::Resources::Resources (const VFS::Manager* vfs, const std::string& base const char * const *extensions) : mBaseDirectory (baseDirectory), mType (type) { + recreate(vfs, extensions); +} + +void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const *extensions) +{ + mFiles.clear(); + mIndex.clear(); + int baseSize = mBaseDirectory.size(); const std::map& index = vfs->getIndex(); diff --git a/apps/opencs/model/world/resources.hpp b/apps/opencs/model/world/resources.hpp index d6998da9f..5e9872ea8 100644 --- a/apps/opencs/model/world/resources.hpp +++ b/apps/opencs/model/world/resources.hpp @@ -27,6 +27,8 @@ namespace CSMWorld Resources (const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type, const char * const *extensions = 0); + void recreate(const VFS::Manager* vfs, const char * const *extensions = 0); + int getSize() const; std::string getId (int index) const; diff --git a/apps/opencs/model/world/resourcesmanager.cpp b/apps/opencs/model/world/resourcesmanager.cpp index 016799be3..6b271c276 100644 --- a/apps/opencs/model/world/resourcesmanager.cpp +++ b/apps/opencs/model/world/resourcesmanager.cpp @@ -14,7 +14,7 @@ void CSMWorld::ResourcesManager::addResources (const Resources& resources) resources)); } -void CSMWorld::ResourcesManager::setVFS(const VFS::Manager *vfs) +void CSMWorld::ResourcesManager::setVFS(VFS::Manager *vfs) { mVFS = vfs; mResources.clear(); @@ -31,11 +31,26 @@ void CSMWorld::ResourcesManager::setVFS(const VFS::Manager *vfs) addResources (Resources (vfs, "videos", UniversalId::Type_Video)); } -const VFS::Manager* CSMWorld::ResourcesManager::getVFS() const +VFS::Manager* CSMWorld::ResourcesManager::getVFS() const { return mVFS; } +void CSMWorld::ResourcesManager::recreateResources() +{ + // TODO make this shared with setVFS function + static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2", 0 }; + + std::map::iterator it = mResources.begin(); + for ( ; it != mResources.end(); ++it) + { + if (it->first == UniversalId::Type_Mesh) + it->second.recreate(mVFS, sMeshTypes); + else + it->second.recreate(mVFS); + } +} + const CSMWorld::Resources& CSMWorld::ResourcesManager::get (UniversalId::Type type) const { std::map::const_iterator iter = mResources.find (type); diff --git a/apps/opencs/model/world/resourcesmanager.hpp b/apps/opencs/model/world/resourcesmanager.hpp index 1ce06f2d3..969666856 100644 --- a/apps/opencs/model/world/resourcesmanager.hpp +++ b/apps/opencs/model/world/resourcesmanager.hpp @@ -16,7 +16,7 @@ namespace CSMWorld class ResourcesManager { std::map mResources; - const VFS::Manager* mVFS; + VFS::Manager* mVFS; private: @@ -26,9 +26,11 @@ namespace CSMWorld ResourcesManager(); - const VFS::Manager* getVFS() const; + VFS::Manager* getVFS() const; - void setVFS(const VFS::Manager* vfs); + void setVFS(VFS::Manager* vfs); + + void recreateResources(); const Resources& get (UniversalId::Type type) const; }; diff --git a/apps/opencs/model/world/resourcetable.cpp b/apps/opencs/model/world/resourcetable.cpp index 5227ec3e6..f55f87873 100644 --- a/apps/opencs/model/world/resourcetable.cpp +++ b/apps/opencs/model/world/resourcetable.cpp @@ -154,3 +154,13 @@ int CSMWorld::ResourceTable::getColumnId (int column) const return -1; } + +void CSMWorld::ResourceTable::beginReset() +{ + beginResetModel(); +} + +void CSMWorld::ResourceTable::endReset() +{ + endResetModel(); +} diff --git a/apps/opencs/model/world/resourcetable.hpp b/apps/opencs/model/world/resourcetable.hpp index 88dcc24b0..7d538df53 100644 --- a/apps/opencs/model/world/resourcetable.hpp +++ b/apps/opencs/model/world/resourcetable.hpp @@ -52,7 +52,12 @@ namespace CSMWorld /// Is \a id flagged as deleted? virtual bool isDeleted (const std::string& id) const; - virtual int getColumnId (int column) const; + virtual int getColumnId (int column) const; + + /// Signal Qt that the data is about to change. + void beginReset(); + /// Signal Qt that the data has been changed. + void endReset(); }; } diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index ff49a90fd..92ed07daf 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -284,6 +284,13 @@ void CSVDoc::View::setupAssetsMenu() { QMenu *assets = menuBar()->addMenu (tr ("Assets")); + QAction *reload = new QAction (tr ("Reload"), this); + connect (reload, SIGNAL (triggered()), &mDocument->getData(), SLOT (assetsChanged())); + setupShortcut("document-assets-reload", reload); + assets->addAction (reload); + + assets->addSeparator(); + QAction *sounds = new QAction (tr ("Sounds"), this); connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView())); setupShortcut("document-assets-sounds", sounds); @@ -889,6 +896,7 @@ void CSVDoc::View::addMetaDataSubView() addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_MetaData, "sys::meta")); } + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/components/vfs/archive.hpp b/components/vfs/archive.hpp index b36c7117b..9bdf12c23 100644 --- a/components/vfs/archive.hpp +++ b/components/vfs/archive.hpp @@ -21,6 +21,9 @@ namespace VFS public: virtual ~Archive() {} + /// Clears cached data for archives that may change. + virtual void resetIfNotStatic(){}; + /// List all resources contained in this archive, and run the resource names through the given normalize function. virtual void listResources(std::map& out, char (*normalize_function) (char)) = 0; }; diff --git a/components/vfs/filesystemarchive.cpp b/components/vfs/filesystemarchive.cpp index ad5150a44..9240909ad 100644 --- a/components/vfs/filesystemarchive.cpp +++ b/components/vfs/filesystemarchive.cpp @@ -12,6 +12,12 @@ namespace VFS } + void FileSystemArchive::resetIfNotStatic() + { + mIndex.clear(); + mBuiltIndex = false; + } + void FileSystemArchive::listResources(std::map &out, char (*normalize_function)(char)) { if (!mBuiltIndex) diff --git a/components/vfs/filesystemarchive.hpp b/components/vfs/filesystemarchive.hpp index 6c8e1b82b..16c2d65ea 100644 --- a/components/vfs/filesystemarchive.hpp +++ b/components/vfs/filesystemarchive.hpp @@ -23,6 +23,8 @@ namespace VFS public: FileSystemArchive(const std::string& path); + virtual void resetIfNotStatic(); + virtual void listResources(std::map& out, char (*normalize_function) (char)); diff --git a/components/vfs/manager.cpp b/components/vfs/manager.cpp index 457947d40..037fef325 100644 --- a/components/vfs/manager.cpp +++ b/components/vfs/manager.cpp @@ -57,6 +57,14 @@ namespace VFS (*it)->listResources(mIndex, mStrict ? &strict_normalize_char : &nonstrict_normalize_char); } + void Manager::rebuildIndex() + { + for (std::vector::const_iterator it = mArchives.begin(); it != mArchives.end(); ++it) + (*it)->resetIfNotStatic(); + + buildIndex(); + } + Files::IStreamPtr Manager::get(const std::string &name) const { std::string normalized = name; diff --git a/components/vfs/manager.hpp b/components/vfs/manager.hpp index 6592a65a8..2ad7cf643 100644 --- a/components/vfs/manager.hpp +++ b/components/vfs/manager.hpp @@ -33,6 +33,9 @@ namespace VFS /// Build the file index. Should be called when all archives have been registered. void buildIndex(); + /// Rebuild the file index. New/deleted files (actual files, not bsa's) will be reflected. + void rebuildIndex(); + /// Does a file with this name exist? /// @note May be called from any thread once the index has been built. bool exists(const std::string& name) const; From 742bd00ec6e7b1802f8bf8a78d76a400885f0b25 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sat, 19 Aug 2017 15:26:46 -0400 Subject: [PATCH 02/12] Clear cached resources --- apps/opencs/model/world/data.cpp | 3 +++ components/resource/resourcemanager.cpp | 5 +++++ components/resource/resourcemanager.hpp | 3 +++ components/resource/resourcesystem.cpp | 10 ++++++++++ components/resource/resourcesystem.hpp | 3 +++ 5 files changed, 24 insertions(+) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 8c25faaa5..633b1ae20 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -1244,6 +1244,9 @@ void CSMWorld::Data::assetsChanged() soundResTable->endReset(); texTable->endReset(); vidTable->endReset(); + + // Get rid of potentially old cached assets + mResourceSystem->clearCache(); } void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) diff --git a/components/resource/resourcemanager.cpp b/components/resource/resourcemanager.cpp index d19d9cf80..4e48d9745 100644 --- a/components/resource/resourcemanager.cpp +++ b/components/resource/resourcemanager.cpp @@ -23,6 +23,11 @@ namespace Resource mCache->removeExpiredObjectsInCache(referenceTime - mExpiryDelay); } + void ResourceManager::clearCache() + { + mCache->clear(); + } + void ResourceManager::setExpiryDelay(double expiryDelay) { mExpiryDelay = expiryDelay; diff --git a/components/resource/resourcemanager.hpp b/components/resource/resourcemanager.hpp index 61599cd5e..58200993b 100644 --- a/components/resource/resourcemanager.hpp +++ b/components/resource/resourcemanager.hpp @@ -28,6 +28,9 @@ namespace Resource /// Clear cache entries that have not been referenced for longer than expiryDelay. virtual void updateCache(double referenceTime); + /// Clear all cache entries. + virtual void clearCache(); + /// How long to keep objects in cache after no longer being referenced. void setExpiryDelay (double expiryDelay); diff --git a/components/resource/resourcesystem.cpp b/components/resource/resourcesystem.cpp index 8d05a1b4e..a9686e5db 100644 --- a/components/resource/resourcesystem.cpp +++ b/components/resource/resourcesystem.cpp @@ -2,6 +2,8 @@ #include +#include + #include "scenemanager.hpp" #include "imagemanager.hpp" #include "niffilemanager.hpp" @@ -68,6 +70,14 @@ namespace Resource (*it)->updateCache(referenceTime); } + void ResourceSystem::clearCache() + { + for (std::vector::iterator it = mResourceManagers.begin(); it != mResourceManagers.end(); ++it) + (*it)->clearCache(); + + osgDB::Registry::instance()->clearObjectCache(); + } + void ResourceSystem::addResourceManager(ResourceManager *resourceMgr) { mResourceManagers.push_back(resourceMgr); diff --git a/components/resource/resourcesystem.hpp b/components/resource/resourcesystem.hpp index dc608b875..ef9ac9647 100644 --- a/components/resource/resourcesystem.hpp +++ b/components/resource/resourcesystem.hpp @@ -41,6 +41,9 @@ namespace Resource /// @note May be called from any thread if you do not add or remove resource managers at that point. void updateCache(double referenceTime); + /// Indicates to each resource manager to clear the entire cache. + void clearCache(); + /// Add this ResourceManager to be handled by the ResourceSystem. /// @note Does not transfer ownership. void addResourceManager(ResourceManager* resourceMgr); From 5950b26912893b40333586c32e49c737a232d148 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sat, 19 Aug 2017 19:36:45 -0400 Subject: [PATCH 03/12] Update scene assets --- apps/opencs/model/world/data.cpp | 2 ++ apps/opencs/model/world/data.hpp | 2 ++ apps/opencs/view/render/cell.cpp | 9 +++++++++ apps/opencs/view/render/cell.hpp | 2 ++ apps/opencs/view/render/object.cpp | 6 ++++++ apps/opencs/view/render/object.hpp | 3 +++ apps/opencs/view/render/pagedworldspacewidget.cpp | 14 +++++++++++++- apps/opencs/view/render/pagedworldspacewidget.hpp | 4 +++- apps/opencs/view/render/previewwidget.cpp | 8 ++++++++ apps/opencs/view/render/previewwidget.hpp | 2 ++ .../opencs/view/render/unpagedworldspacewidget.cpp | 9 +++++++++ .../opencs/view/render/unpagedworldspacewidget.hpp | 2 ++ components/resource/resourcesystem.cpp | 2 -- 13 files changed, 61 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 633b1ae20..61db4ff77 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -1247,6 +1247,8 @@ void CSMWorld::Data::assetsChanged() // Get rid of potentially old cached assets mResourceSystem->clearCache(); + + emit assetTablesChanged(); } void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 8bc1c4271..8fe5eeff9 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -304,6 +304,8 @@ namespace CSMWorld void idListChanged(); + void assetTablesChanged(); + private slots: void assetsChanged(); diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 48156359f..4b06432d6 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -283,6 +283,15 @@ void CSVRender::Cell::pathgridRemoved() mPathgrid->removeGeometry(); } +void CSVRender::Cell::reloadAssets() +{ + for (std::map::const_iterator iter (mObjects.begin()); + iter != mObjects.end(); ++iter) + { + iter->second->reloadAssets(); + } +} + void CSVRender::Cell::setSelection (int elementMask, Selection mode) { if (elementMask & Mask_Reference) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index ca82dd580..f53f61973 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -118,6 +118,8 @@ namespace CSVRender void pathgridRemoved(); + void reloadAssets(); + void setSelection (int elementMask, Selection mode); // Select everything that references the same ID as at least one of the elements diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index eb90e9db3..522057097 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -532,6 +532,12 @@ bool CSVRender::Object::referenceDataChanged (const QModelIndex& topLeft, return false; } +void CSVRender::Object::reloadAssets() +{ + update(); + updateMarker(); +} + std::string CSVRender::Object::getReferenceId() const { return mReferenceId; diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index e28e2562c..e14697e62 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -151,6 +151,9 @@ namespace CSVRender /// this object? bool referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + /// Reloads the underlying asset + void reloadAssets(); + /// Returns an empty string if this is a refereceable-type object. std::string getReferenceId() const; diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index b5497558a..b1077139c 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -472,6 +472,9 @@ CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)), this, SLOT (cellAdded (const QModelIndex&, int, int))); + connect (&document.getData(), SIGNAL (assetTablesChanged ()), + this, SLOT (assetTablesChanged ())); + // Shortcuts CSMPrefs::Shortcut* loadCameraCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-cell", this); connect(loadCameraCellShortcut, SIGNAL(activated()), this, SLOT(loadCameraCell())); @@ -520,7 +523,7 @@ void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) // Loop through all the coordinates to add them to selection while (stream >> ignore1 >> ignore2 >> x >> y) selection.add (CSMWorld::CellCoordinates (x, y)); - + // Mark that camera needs setup mCamPositionSet=false; } @@ -763,6 +766,15 @@ void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int flagAsModified(); } +void CSVRender::PagedWorldspaceWidget::assetTablesChanged() +{ + std::map::iterator iter = mCells.begin(); + for ( ; iter != mCells.end(); ++iter) + { + iter->second->reloadAssets(); + } +} + void CSVRender::PagedWorldspaceWidget::loadCameraCell() { addCellToSceneFromCamera(0, 0); diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 0663d3424..8c41df51e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -84,7 +84,7 @@ namespace CSVRender /// hint system. virtual ~PagedWorldspaceWidget(); - + /// Decodes the the hint string to set of cell that are rendered. void useViewHint (const std::string& hint); @@ -155,6 +155,8 @@ namespace CSVRender virtual void cellAdded (const QModelIndex& index, int start, int end); + void assetTablesChanged (); + void loadCameraCell(); void loadEastCell(); diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 2f3510317..972fb556d 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -17,6 +17,9 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (referenceableAboutToBeRemoved (const QModelIndex&, int, int))); + connect (&mData, SIGNAL (assetTablesChanged ()), + this, SLOT (assetTablesChanged ())); + if (!referenceable) { QAbstractItemModel *references = @@ -119,3 +122,8 @@ void CSVRender::PreviewWidget::referenceAboutToBeRemoved (const QModelIndex& par if (index.row()>=start && index.row()<=end) emit closeRequest(); } + +void CSVRender::PreviewWidget::assetTablesChanged () +{ + mObject.reloadAssets(); +} diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index 73f7dc810..630ccf293 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -47,6 +47,8 @@ namespace CSVRender void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + void assetTablesChanged (); }; } diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index b82aa45b2..3201f7303 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -47,6 +47,9 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& connect (mCellsModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (cellRowsAboutToBeRemoved (const QModelIndex&, int, int))); + connect (&document.getData(), SIGNAL (assetTablesChanged ()), + this, SLOT (assetTablesChanged ())); + update(); mCell.reset (new Cell (document.getData(), mRootNode, mCellId)); @@ -82,6 +85,12 @@ void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelI emit closeRequest(); } +void CSVRender::UnpagedWorldspaceWidget::assetTablesChanged() +{ + if (mCell) + mCell->reloadAssets(); +} + bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector& universalIdData, DropType type) { if (WorldspaceWidget::handleDrop (universalIdData, type)) diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 5283b3a97..527463990 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -108,6 +108,8 @@ namespace CSVRender void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void assetTablesChanged (); + signals: void cellChanged(const CSMWorld::UniversalId& id); diff --git a/components/resource/resourcesystem.cpp b/components/resource/resourcesystem.cpp index a9686e5db..b1061adcd 100644 --- a/components/resource/resourcesystem.cpp +++ b/components/resource/resourcesystem.cpp @@ -74,8 +74,6 @@ namespace Resource { for (std::vector::iterator it = mResourceManagers.begin(); it != mResourceManagers.end(); ++it) (*it)->clearCache(); - - osgDB::Registry::instance()->clearObjectCache(); } void ResourceSystem::addResourceManager(ResourceManager *resourceMgr) From d7744e8b16a1f4887abbc036b755d3356eada244 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sun, 20 Aug 2017 19:07:23 -0400 Subject: [PATCH 04/12] A bit of cleanup --- apps/opencs/model/doc/document.cpp | 2 +- apps/opencs/model/world/data.cpp | 9 ++++---- apps/opencs/model/world/data.hpp | 3 ++- apps/opencs/model/world/resourcesmanager.cpp | 22 ++++++++++---------- apps/opencs/model/world/resourcesmanager.hpp | 8 ++++--- components/resource/resourcesystem.cpp | 2 -- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index a7809f3e3..d9f86cdde 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -275,7 +275,7 @@ CSMDoc::Document::Document (VFS::Manager* vfs, const Files::ConfigurationManager const Fallback::Map* fallback, ToUTF8::FromType encoding, CSMWorld::ResourcesManager& resourcesManager, const std::vector& blacklistedScripts) -: mVFS(vfs), mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager, fallback, resDir), +: mVFS(vfs), mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, vfs, resourcesManager, fallback, resDir), mTools (*this, encoding), mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 61db4ff77..d7f42d027 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -62,9 +62,9 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec return number; } -CSMWorld::Data::Data (ToUTF8::FromType encoding, ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir) +CSMWorld::Data::Data (ToUTF8::FromType encoding, VFS::Manager* vfs, ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir) : mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), - mResourcesManager (resourcesManager), mFallbackMap(fallback), + mVFS(vfs), mResourcesManager (resourcesManager), mFallbackMap(fallback), mReader (0), mDialogue (0), mReaderIndex(1), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS())) { mResourceSystem->getSceneManager()->setShaderPath((resDir / "shaders").string()); @@ -1218,8 +1218,7 @@ std::vector CSMWorld::Data::getIds (bool listDeleted) const void CSMWorld::Data::assetsChanged() { - VFS::Manager* vfs = mResourcesManager.getVFS(); - vfs->rebuildIndex(); + mVFS->rebuildIndex(); ResourceTable* meshTable = static_cast(getTableModel(UniversalId::Type_Meshes)); ResourceTable* iconTable = static_cast(getTableModel(UniversalId::Type_Icons)); @@ -1264,7 +1263,7 @@ void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end) const VFS::Manager* CSMWorld::Data::getVFS() const { - return mResourcesManager.getVFS(); + return mVFS; } const Fallback::Map* CSMWorld::Data::getFallbackMap() const diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 8fe5eeff9..771a706b3 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -108,6 +108,7 @@ namespace CSMWorld RefCollection mRefs; IdCollection mFilters; Collection mMetaData; + VFS::Manager* mVFS; ResourcesManager& mResourcesManager; const Fallback::Map* mFallbackMap; std::vector mModels; @@ -140,7 +141,7 @@ namespace CSMWorld public: - Data (ToUTF8::FromType encoding, ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir); + Data (ToUTF8::FromType encoding, VFS::Manager* vfs, ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir); virtual ~Data(); diff --git a/apps/opencs/model/world/resourcesmanager.cpp b/apps/opencs/model/world/resourcesmanager.cpp index 6b271c276..c50b86682 100644 --- a/apps/opencs/model/world/resourcesmanager.cpp +++ b/apps/opencs/model/world/resourcesmanager.cpp @@ -14,16 +14,19 @@ void CSMWorld::ResourcesManager::addResources (const Resources& resources) resources)); } -void CSMWorld::ResourcesManager::setVFS(VFS::Manager *vfs) +const char * const * CSMWorld::ResourcesManager::getMeshExtensions() { - mVFS = vfs; - mResources.clear(); - // maybe we could go over the osgDB::Registry to list all supported node formats - static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2", 0 }; + return sMeshTypes; +} - addResources (Resources (vfs, "meshes", UniversalId::Type_Mesh, sMeshTypes)); +void CSMWorld::ResourcesManager::setVFS(const VFS::Manager *vfs) +{ + mVFS = vfs; + mResources.clear(); + + addResources (Resources (vfs, "meshes", UniversalId::Type_Mesh, getMeshExtensions())); addResources (Resources (vfs, "icons", UniversalId::Type_Icon)); addResources (Resources (vfs, "music", UniversalId::Type_Music)); addResources (Resources (vfs, "sound", UniversalId::Type_SoundRes)); @@ -31,21 +34,18 @@ void CSMWorld::ResourcesManager::setVFS(VFS::Manager *vfs) addResources (Resources (vfs, "videos", UniversalId::Type_Video)); } -VFS::Manager* CSMWorld::ResourcesManager::getVFS() const +const VFS::Manager* CSMWorld::ResourcesManager::getVFS() const { return mVFS; } void CSMWorld::ResourcesManager::recreateResources() { - // TODO make this shared with setVFS function - static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2", 0 }; - std::map::iterator it = mResources.begin(); for ( ; it != mResources.end(); ++it) { if (it->first == UniversalId::Type_Mesh) - it->second.recreate(mVFS, sMeshTypes); + it->second.recreate(mVFS, getMeshExtensions()); else it->second.recreate(mVFS); } diff --git a/apps/opencs/model/world/resourcesmanager.hpp b/apps/opencs/model/world/resourcesmanager.hpp index 969666856..0e8385300 100644 --- a/apps/opencs/model/world/resourcesmanager.hpp +++ b/apps/opencs/model/world/resourcesmanager.hpp @@ -16,19 +16,21 @@ namespace CSMWorld class ResourcesManager { std::map mResources; - VFS::Manager* mVFS; + const VFS::Manager* mVFS; private: void addResources (const Resources& resources); + const char * const * getMeshExtensions(); + public: ResourcesManager(); - VFS::Manager* getVFS() const; + const VFS::Manager* getVFS() const; - void setVFS(VFS::Manager* vfs); + void setVFS(const VFS::Manager* vfs); void recreateResources(); diff --git a/components/resource/resourcesystem.cpp b/components/resource/resourcesystem.cpp index b1061adcd..d7a6771c4 100644 --- a/components/resource/resourcesystem.cpp +++ b/components/resource/resourcesystem.cpp @@ -2,8 +2,6 @@ #include -#include - #include "scenemanager.hpp" #include "imagemanager.hpp" #include "niffilemanager.hpp" From 7914fd5c9c42ea4c678a925253d495429c049248 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sun, 20 Aug 2017 19:36:21 -0400 Subject: [PATCH 05/12] Re-index BSAs --- components/vfs/archive.hpp | 4 ++-- components/vfs/bsaarchive.cpp | 24 ++++++++++++++++++------ components/vfs/bsaarchive.hpp | 5 +++++ components/vfs/filesystemarchive.cpp | 2 +- components/vfs/filesystemarchive.hpp | 2 +- components/vfs/manager.cpp | 2 +- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/components/vfs/archive.hpp b/components/vfs/archive.hpp index 9bdf12c23..f2082f750 100644 --- a/components/vfs/archive.hpp +++ b/components/vfs/archive.hpp @@ -21,8 +21,8 @@ namespace VFS public: virtual ~Archive() {} - /// Clears cached data for archives that may change. - virtual void resetIfNotStatic(){}; + /// Clears cached data. + virtual void reset() = 0; /// List all resources contained in this archive, and run the resource names through the given normalize function. virtual void listResources(std::map& out, char (*normalize_function) (char)) = 0; diff --git a/components/vfs/bsaarchive.cpp b/components/vfs/bsaarchive.cpp index a527a6ad9..88e6bf2c7 100644 --- a/components/vfs/bsaarchive.cpp +++ b/components/vfs/bsaarchive.cpp @@ -5,14 +5,15 @@ namespace VFS BsaArchive::BsaArchive(const std::string &filename) + : mFileName(filename) { - mFile.open(filename); + load(); +} - const Bsa::BSAFile::FileList &filelist = mFile.getList(); - for(Bsa::BSAFile::FileList::const_iterator it = filelist.begin();it != filelist.end();++it) - { - mResources.push_back(BsaArchiveFile(&*it, &mFile)); - } +void BsaArchive::reset() +{ + mResources.clear(); + load(); } void BsaArchive::listResources(std::map &out, char (*normalize_function)(char)) @@ -26,6 +27,17 @@ void BsaArchive::listResources(std::map &out, char (*normal } } +void BsaArchive::load() +{ + mFile.open(mFileName); + + const Bsa::BSAFile::FileList &filelist = mFile.getList(); + for(Bsa::BSAFile::FileList::const_iterator it = filelist.begin();it != filelist.end();++it) + { + mResources.push_back(BsaArchiveFile(&*it, &mFile)); + } +} + // ------------------------------------------------------------------------------ BsaArchiveFile::BsaArchiveFile(const Bsa::BSAFile::FileStruct *info, Bsa::BSAFile* bsa) diff --git a/components/vfs/bsaarchive.hpp b/components/vfs/bsaarchive.hpp index a6e274037..92204f90c 100644 --- a/components/vfs/bsaarchive.hpp +++ b/components/vfs/bsaarchive.hpp @@ -24,9 +24,14 @@ namespace VFS public: BsaArchive(const std::string& filename); + virtual void reset(); + virtual void listResources(std::map& out, char (*normalize_function) (char)); private: + void load(); + + std::string mFileName; Bsa::BSAFile mFile; std::vector mResources; diff --git a/components/vfs/filesystemarchive.cpp b/components/vfs/filesystemarchive.cpp index 9240909ad..8fb992e76 100644 --- a/components/vfs/filesystemarchive.cpp +++ b/components/vfs/filesystemarchive.cpp @@ -12,7 +12,7 @@ namespace VFS } - void FileSystemArchive::resetIfNotStatic() + void FileSystemArchive::reset() { mIndex.clear(); mBuiltIndex = false; diff --git a/components/vfs/filesystemarchive.hpp b/components/vfs/filesystemarchive.hpp index 16c2d65ea..5843bf871 100644 --- a/components/vfs/filesystemarchive.hpp +++ b/components/vfs/filesystemarchive.hpp @@ -23,7 +23,7 @@ namespace VFS public: FileSystemArchive(const std::string& path); - virtual void resetIfNotStatic(); + virtual void reset(); virtual void listResources(std::map& out, char (*normalize_function) (char)); diff --git a/components/vfs/manager.cpp b/components/vfs/manager.cpp index 037fef325..9b1798e8f 100644 --- a/components/vfs/manager.cpp +++ b/components/vfs/manager.cpp @@ -60,7 +60,7 @@ namespace VFS void Manager::rebuildIndex() { for (std::vector::const_iterator it = mArchives.begin(); it != mArchives.end(); ++it) - (*it)->resetIfNotStatic(); + (*it)->reset(); buildIndex(); } From b62cb0e2a47d5252d686ee2770ddc6fb6711a194 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sun, 20 Aug 2017 19:55:16 -0400 Subject: [PATCH 06/12] Clear out GPU texture/stateset cache --- components/resource/scenemanager.cpp | 16 ++++++++++++++++ components/resource/scenemanager.hpp | 2 ++ 2 files changed, 18 insertions(+) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 226933760..2f04aa7c2 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -122,6 +122,13 @@ namespace Resource { return _sharedStateSetList.size(); } + + void clearCache() + { + OpenThreads::ScopedLock lock(_listMutex); + _sharedTextureList.clear(); + _sharedStateSetList.clear(); + } }; /// Set texture filtering settings on textures contained in a FlipController. @@ -710,6 +717,15 @@ namespace Resource mSharedStateMutex.unlock(); } + void SceneManager::clearCache() + { + ResourceManager::clearCache(); + + mSharedStateMutex.lock(); + mSharedStateManager->clearCache(); + mSharedStateMutex.unlock(); + } + void SceneManager::reportStats(unsigned int frameNumber, osg::Stats *stats) const { { diff --git a/components/resource/scenemanager.hpp b/components/resource/scenemanager.hpp index c6ff02acf..14032df77 100644 --- a/components/resource/scenemanager.hpp +++ b/components/resource/scenemanager.hpp @@ -143,6 +143,8 @@ namespace Resource /// @see ResourceManager::updateCache virtual void updateCache(double referenceTime); + virtual void clearCache(); + virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) const; private: From d4a722067db0aeeac725ea654ab70f36a8eee968 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sun, 20 Aug 2017 20:55:56 -0400 Subject: [PATCH 07/12] Reload water --- apps/opencs/view/render/cell.cpp | 2 ++ apps/opencs/view/render/cellwater.cpp | 5 +++++ apps/opencs/view/render/cellwater.hpp | 2 ++ 3 files changed, 9 insertions(+) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 4b06432d6..ebc383ff2 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -290,6 +290,8 @@ void CSVRender::Cell::reloadAssets() { iter->second->reloadAssets(); } + + mCellWater->reloadAssets(); } void CSVRender::Cell::setSelection (int elementMask, Selection mode) diff --git a/apps/opencs/view/render/cellwater.cpp b/apps/opencs/view/render/cellwater.cpp index 15ea15cc4..d7e8669ef 100644 --- a/apps/opencs/view/render/cellwater.cpp +++ b/apps/opencs/view/render/cellwater.cpp @@ -92,6 +92,11 @@ namespace CSVRender } } + void CellWater::reloadAssets() + { + recreate(); + } + void CellWater::cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { const CSMWorld::Collection& cells = mData.getCells(); diff --git a/apps/opencs/view/render/cellwater.hpp b/apps/opencs/view/render/cellwater.hpp index d2ed9b458..47e586707 100644 --- a/apps/opencs/view/render/cellwater.hpp +++ b/apps/opencs/view/render/cellwater.hpp @@ -42,6 +42,8 @@ namespace CSVRender void updateCellData(const CSMWorld::Record& cellRecord); + void reloadAssets(); + private slots: void cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); From 3b9326d238f0dd2da0afd47e0a96dda8aa401e0b Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sun, 20 Aug 2017 22:34:41 -0400 Subject: [PATCH 08/12] Clear terrain cache and reload terrain --- apps/opencs/view/render/cell.cpp | 7 +++++++ components/terrain/buffercache.cpp | 12 ++++++++++++ components/terrain/buffercache.hpp | 2 ++ components/terrain/chunkmanager.cpp | 7 +++++++ components/terrain/chunkmanager.hpp | 2 ++ components/terrain/world.cpp | 6 ++++++ components/terrain/world.hpp | 3 +++ 7 files changed, 39 insertions(+) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index ebc383ff2..5aa534232 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -291,6 +291,13 @@ void CSVRender::Cell::reloadAssets() iter->second->reloadAssets(); } + if (mTerrain) + { + mTerrain->unloadCell(mCoordinates.getX(), mCoordinates.getY()); + mTerrain->clearCache(); + mTerrain->loadCell(mCoordinates.getX(), mCoordinates.getY()); + } + mCellWater->reloadAssets(); } diff --git a/components/terrain/buffercache.cpp b/components/terrain/buffercache.cpp index 470655539..361dd6c04 100644 --- a/components/terrain/buffercache.cpp +++ b/components/terrain/buffercache.cpp @@ -231,4 +231,16 @@ namespace Terrain return buffer; } + void BufferCache::clearCache() + { + { + OpenThreads::ScopedLock lock(mIndexBufferMutex); + mIndexBufferMap.clear(); + } + { + OpenThreads::ScopedLock lock(mUvBufferMutex); + mUvBufferMap.clear(); + } + } + } diff --git a/components/terrain/buffercache.hpp b/components/terrain/buffercache.hpp index e8963354b..bfdf558bc 100644 --- a/components/terrain/buffercache.hpp +++ b/components/terrain/buffercache.hpp @@ -22,6 +22,8 @@ namespace Terrain /// @note Thread safe. osg::ref_ptr getUVBuffer(unsigned int numVerts); + void clearCache(); + // TODO: add releaseGLObjects() for our vertex/element buffer objects private: diff --git a/components/terrain/chunkmanager.cpp b/components/terrain/chunkmanager.cpp index e4a7c2d68..ea71c726f 100644 --- a/components/terrain/chunkmanager.cpp +++ b/components/terrain/chunkmanager.cpp @@ -55,6 +55,13 @@ void ChunkManager::reportStats(unsigned int frameNumber, osg::Stats *stats) cons stats->setAttribute(frameNumber, "Terrain Chunk", mCache->getCacheSize()); } +void ChunkManager::clearCache() +{ + ResourceManager::clearCache(); + + mBufferCache.clearCache(); +} + void ChunkManager::setCullingActive(bool active) { mCullingActive = active; diff --git a/components/terrain/chunkmanager.hpp b/components/terrain/chunkmanager.hpp index 553e06d97..2f92fa836 100644 --- a/components/terrain/chunkmanager.hpp +++ b/components/terrain/chunkmanager.hpp @@ -34,6 +34,8 @@ namespace Terrain virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) const; + virtual void clearCache(); + void setCullingActive(bool active); private: diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index b7cc0ae01..9bbb585a8 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -70,6 +70,12 @@ float World::getHeightAt(const osg::Vec3f &worldPos) return mStorage->getHeightAt(worldPos); } +void World::clearCache() +{ + mTextureManager->clearCache(); + mChunkManager->clearCache(); +} + void World::updateTextureFiltering() { mTextureManager->updateTextureFiltering(); diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index d0576fbd3..2fb669494 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -67,6 +67,9 @@ namespace Terrain /// @note Thread safe. virtual void cacheCell(View* view, int x, int y) {} + /// Clears cached texture and chunk data. + virtual void clearCache(); + /// Load the cell into the scene graph. /// @note Not thread safe. /// @note May be ignored by derived implementations that don't organize the terrain into cells. From 679a2847355e722bd1bd600a246985828c36f79d Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Mon, 21 Aug 2017 13:33:11 -0400 Subject: [PATCH 09/12] Use scoped lock instead of directly locking/unlocking mutex --- components/resource/scenemanager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 2f04aa7c2..aba1d454e 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -721,9 +721,8 @@ namespace Resource { ResourceManager::clearCache(); - mSharedStateMutex.lock(); + OpenThreads::ScopedLock lock(mSharedStateMutex); mSharedStateManager->clearCache(); - mSharedStateMutex.unlock(); } void SceneManager::reportStats(unsigned int frameNumber, osg::Stats *stats) const From 979b0d7211ab0a8db8dd27bb7a69db3c70bf2ad3 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Mon, 21 Aug 2017 18:58:38 -0400 Subject: [PATCH 10/12] Code cleanup and more cache clearing --- apps/opencs/model/world/data.cpp | 40 ++++++++++++---------- apps/opencs/view/doc/view.cpp | 1 - apps/opencs/view/render/cell.cpp | 1 - components/resource/bulletshapemanager.cpp | 7 ++++ components/resource/bulletshapemanager.hpp | 2 ++ components/resource/multiobjectcache.cpp | 6 ++++ components/resource/multiobjectcache.hpp | 3 ++ components/resource/resourcesystem.hpp | 1 + components/resource/scenemanager.cpp | 1 + components/terrain/world.cpp | 6 ---- components/terrain/world.hpp | 3 -- 11 files changed, 41 insertions(+), 30 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index d7f42d027..39c0291fc 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -1220,29 +1220,31 @@ void CSMWorld::Data::assetsChanged() { mVFS->rebuildIndex(); - ResourceTable* meshTable = static_cast(getTableModel(UniversalId::Type_Meshes)); - ResourceTable* iconTable = static_cast(getTableModel(UniversalId::Type_Icons)); - ResourceTable* musicTable = static_cast(getTableModel(UniversalId::Type_Musics)); - ResourceTable* soundResTable = static_cast(getTableModel(UniversalId::Type_SoundsRes)); - ResourceTable* texTable = static_cast(getTableModel(UniversalId::Type_Textures)); - ResourceTable* vidTable = static_cast(getTableModel(UniversalId::Type_Videos)); - - meshTable->beginReset(); - iconTable->beginReset(); - musicTable->beginReset(); - soundResTable->beginReset(); - texTable->beginReset(); - vidTable->beginReset(); + const UniversalId assetTableIds[] = { + UniversalId::Type_Meshes, + UniversalId::Type_Icons, + UniversalId::Type_Musics, + UniversalId::Type_SoundsRes, + UniversalId::Type_Textures, + UniversalId::Type_Videos + }; + + size_t numAssetTables = sizeof(assetTableIds) / sizeof(UniversalId); + + for (size_t i = 0; i < numAssetTables; ++i) + { + ResourceTable* table = static_cast(getTableModel(assetTableIds[i])); + table->beginReset(); + } // Trigger recreation mResourcesManager.recreateResources(); - meshTable->endReset(); - iconTable->endReset(); - musicTable->endReset(); - soundResTable->endReset(); - texTable->endReset(); - vidTable->endReset(); + for (size_t i = 0; i < numAssetTables; ++i) + { + ResourceTable* table = static_cast(getTableModel(assetTableIds[i])); + table->endReset(); + } // Get rid of potentially old cached assets mResourceSystem->clearCache(); diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 92ed07daf..dfbeea031 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -896,7 +896,6 @@ void CSVDoc::View::addMetaDataSubView() addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_MetaData, "sys::meta")); } - void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 5aa534232..a10e38397 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -294,7 +294,6 @@ void CSVRender::Cell::reloadAssets() if (mTerrain) { mTerrain->unloadCell(mCoordinates.getX(), mCoordinates.getY()); - mTerrain->clearCache(); mTerrain->loadCell(mCoordinates.getX(), mCoordinates.getY()); } diff --git a/components/resource/bulletshapemanager.cpp b/components/resource/bulletshapemanager.cpp index 010917572..c1a7eb8f3 100644 --- a/components/resource/bulletshapemanager.cpp +++ b/components/resource/bulletshapemanager.cpp @@ -190,6 +190,13 @@ void BulletShapeManager::updateCache(double referenceTime) mInstanceCache->removeUnreferencedObjectsInCache(); } +void BulletShapeManager::clearCache() +{ + ResourceManager::clearCache(); + + mInstanceCache->clear(); +} + void BulletShapeManager::reportStats(unsigned int frameNumber, osg::Stats *stats) const { stats->setAttribute(frameNumber, "Shape", mCache->getCacheSize()); diff --git a/components/resource/bulletshapemanager.hpp b/components/resource/bulletshapemanager.hpp index fec7251ac..8ae2b531f 100644 --- a/components/resource/bulletshapemanager.hpp +++ b/components/resource/bulletshapemanager.hpp @@ -42,6 +42,8 @@ namespace Resource /// @see ResourceManager::updateCache virtual void updateCache(double referenceTime); + virtual void clearCache(); + void reportStats(unsigned int frameNumber, osg::Stats *stats) const; private: diff --git a/components/resource/multiobjectcache.cpp b/components/resource/multiobjectcache.cpp index fcda455cc..266139f3c 100644 --- a/components/resource/multiobjectcache.cpp +++ b/components/resource/multiobjectcache.cpp @@ -43,6 +43,12 @@ namespace Resource objectsToRemove.clear(); } + void MultiObjectCache::clear() + { + OpenThreads::ScopedLock lock(_objectCacheMutex); + _objectCache.clear(); + } + void MultiObjectCache::addEntryToObjectCache(const std::string &filename, osg::Object *object) { OpenThreads::ScopedLock lock(_objectCacheMutex); diff --git a/components/resource/multiobjectcache.hpp b/components/resource/multiobjectcache.hpp index a314a9e4b..527247bf9 100644 --- a/components/resource/multiobjectcache.hpp +++ b/components/resource/multiobjectcache.hpp @@ -25,6 +25,9 @@ namespace Resource void removeUnreferencedObjectsInCache(); + /** Remove all objects from the cache. */ + void clear(); + void addEntryToObjectCache(const std::string& filename, osg::Object* object); /** Take an Object from cache. Return NULL if no object found. */ diff --git a/components/resource/resourcesystem.hpp b/components/resource/resourcesystem.hpp index ef9ac9647..efce50b97 100644 --- a/components/resource/resourcesystem.hpp +++ b/components/resource/resourcesystem.hpp @@ -42,6 +42,7 @@ namespace Resource void updateCache(double referenceTime); /// Indicates to each resource manager to clear the entire cache. + /// @note May be called from any thread if you do not add or remove resource managers at that point. void clearCache(); /// Add this ResourceManager to be handled by the ResourceSystem. diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index aba1d454e..69a54bf17 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -723,6 +723,7 @@ namespace Resource OpenThreads::ScopedLock lock(mSharedStateMutex); mSharedStateManager->clearCache(); + mInstanceCache->clear(); } void SceneManager::reportStats(unsigned int frameNumber, osg::Stats *stats) const diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index 9bbb585a8..b7cc0ae01 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -70,12 +70,6 @@ float World::getHeightAt(const osg::Vec3f &worldPos) return mStorage->getHeightAt(worldPos); } -void World::clearCache() -{ - mTextureManager->clearCache(); - mChunkManager->clearCache(); -} - void World::updateTextureFiltering() { mTextureManager->updateTextureFiltering(); diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index 2fb669494..d0576fbd3 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -67,9 +67,6 @@ namespace Terrain /// @note Thread safe. virtual void cacheCell(View* view, int x, int y) {} - /// Clears cached texture and chunk data. - virtual void clearCache(); - /// Load the cell into the scene graph. /// @note Not thread safe. /// @note May be ignored by derived implementations that don't organize the terrain into cells. From 8c4b12a6035588e1e9dfdcc2d4475ac6babd57e8 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Mon, 21 Aug 2017 22:31:19 -0400 Subject: [PATCH 11/12] VFS changes, one VFS and resource system per document. Added ability to reset a VFS::Manager. Removed ability to rebuild the index for a VFS::Manager. Moved VFS creation to CSM::Data. --- apps/opencs/editor.cpp | 9 +-------- apps/opencs/editor.hpp | 10 ---------- apps/opencs/model/doc/document.cpp | 16 ++++++---------- apps/opencs/model/doc/document.hpp | 12 +++++------- apps/opencs/model/doc/documentmanager.cpp | 11 ++++++----- apps/opencs/model/doc/documentmanager.hpp | 20 ++++++++++---------- apps/opencs/model/world/data.cpp | 19 ++++++++++++++----- apps/opencs/model/world/data.hpp | 13 ++++++++++--- components/vfs/archive.hpp | 3 --- components/vfs/bsaarchive.cpp | 6 ------ components/vfs/bsaarchive.hpp | 2 -- components/vfs/filesystemarchive.cpp | 6 ------ components/vfs/filesystemarchive.hpp | 2 -- components/vfs/manager.cpp | 14 ++++++-------- components/vfs/manager.hpp | 6 +++--- 15 files changed, 61 insertions(+), 88 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 54e323956..86c87962d 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -5,9 +5,6 @@ #include #include -#include -#include - #include #include @@ -33,11 +30,7 @@ CS::Editor::Editor () NifOsg::Loader::setShowMarkers(true); - mVFS.reset(new VFS::Manager(mFsStrict)); - - VFS::registerArchives(mVFS.get(), Files::Collections(config.first, !mFsStrict), config.second, true); - - mDocumentManager.setVFS(mVFS.get()); + mDocumentManager.setFileData(mFsStrict, config.first, config.second); mNewGame.setLocalData (mLocal); mFileDialog.setLocalData (mLocal); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index ff670ba1b..b60f5c6a8 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -1,8 +1,6 @@ #ifndef CS_EDITOR_H #define CS_EDITOR_H -#include - #include #include @@ -30,11 +28,6 @@ #include "view/tools/merge.hpp" -namespace VFS -{ - class Manager; -} - namespace CSMDoc { class Document; @@ -46,9 +39,6 @@ namespace CS { Q_OBJECT - // FIXME: should be moved to document, so we can have different resources for each opened project - std::unique_ptr mVFS; - Files::ConfigurationManager mCfgMgr; CSMPrefs::State mSettingsState; CSMDoc::DocumentManager mDocumentManager; diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index d9f86cdde..7257b2fe3 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -269,13 +269,14 @@ void CSMDoc::Document::createBase() } } -CSMDoc::Document::Document (VFS::Manager* vfs, const Files::ConfigurationManager& configuration, - const std::vector< boost::filesystem::path >& files, bool new_, +CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, + const std::vector< boost::filesystem::path >& files,bool new_, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, const Fallback::Map* fallback, - ToUTF8::FromType encoding, CSMWorld::ResourcesManager& resourcesManager, - const std::vector& blacklistedScripts) -: mVFS(vfs), mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, vfs, resourcesManager, fallback, resDir), + ToUTF8::FromType encoding, + const std::vector& blacklistedScripts, + bool fsStrict, const Files::PathContainer& dataPaths, const std::vector& archives) +: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, fsStrict, dataPaths, archives, fallback, resDir), mTools (*this, encoding), mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), @@ -337,11 +338,6 @@ CSMDoc::Document::~Document() { } -const VFS::Manager *CSMDoc::Document::getVFS() const -{ - return mVFS; -} - QUndoStack& CSMDoc::Document::getUndoStack() { return mUndoStack; diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index ad0201407..d31fd5aca 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include "../world/data.hpp" @@ -59,7 +60,6 @@ namespace CSMDoc private: - VFS::Manager* mVFS; boost::filesystem::path mSavePath; std::vector mContentFiles; bool mNew; @@ -102,17 +102,15 @@ namespace CSMDoc public: - Document (VFS::Manager* vfs, const Files::ConfigurationManager& configuration, + Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, bool new_, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, - const Fallback::Map* fallback, - ToUTF8::FromType encoding, CSMWorld::ResourcesManager& resourcesManager, - const std::vector& blacklistedScripts); + const Fallback::Map* fallback, ToUTF8::FromType encoding, + const std::vector& blacklistedScripts, + bool fsStrict, const Files::PathContainer& dataPaths, const std::vector& archives); ~Document(); - const VFS::Manager* getVFS() const; - QUndoStack& getUndoStack(); int getState() const; diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 11378cab4..531cfd267 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -9,7 +9,7 @@ #include "document.hpp" CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration) -: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252), mVFS(NULL) +: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252) { boost::filesystem::path projectPath = configuration.getUserDataPath() / "projects"; @@ -62,7 +62,7 @@ CSMDoc::Document *CSMDoc::DocumentManager::makeDocument ( const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, bool new_) { - return new Document (mVFS, mConfiguration, files, new_, savePath, mResDir, &mFallbackMap, mEncoding, mResourcesManager, mBlacklistedScripts); + return new Document (mConfiguration, files, new_, savePath, mResDir, &mFallbackMap, mEncoding, mBlacklistedScripts, mFsStrict, mDataPaths, mArchives); } void CSMDoc::DocumentManager::insertDocument (CSMDoc::Document *document) @@ -127,8 +127,9 @@ void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std:: removeDocument (document); } -void CSMDoc::DocumentManager::setVFS(VFS::Manager *vfs) +void CSMDoc::DocumentManager::setFileData(bool strict, const Files::PathContainer& dataPaths, const std::vector& archives) { - mResourcesManager.setVFS(vfs); - mVFS = vfs; + mFsStrict = strict; + mDataPaths = dataPaths; + mArchives = archives; } diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 771afe8e5..ae6d9481a 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -11,8 +11,7 @@ #include #include - -#include "../world/resourcesmanager.hpp" +#include #include "loader.hpp" @@ -39,9 +38,14 @@ namespace CSMDoc QThread mLoaderThread; Loader mLoader; ToUTF8::FromType mEncoding; - CSMWorld::ResourcesManager mResourcesManager; std::vector mBlacklistedScripts; - VFS::Manager* mVFS; + + boost::filesystem::path mResDir; + Fallback::Map mFallbackMap; + + bool mFsStrict; + Files::PathContainer mDataPaths; + std::vector mArchives; DocumentManager (const DocumentManager&); DocumentManager& operator= (const DocumentManager&); @@ -74,15 +78,11 @@ namespace CSMDoc void setBlacklistedScripts (const std::vector& scriptIds); - void setVFS(VFS::Manager* vfs); + /// Sets the file data that gets passed to newly created documents. + void setFileData(bool strict, const Files::PathContainer& dataPaths, const std::vector& archives); bool isEmpty(); - private: - - boost::filesystem::path mResDir; - Fallback::Map mFallbackMap; - private slots: void documentLoaded (Document *document); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 39c0291fc..007190e4a 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -12,6 +12,7 @@ #include #include +#include #include "idtable.hpp" #include "idtree.hpp" @@ -62,11 +63,18 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec return number; } -CSMWorld::Data::Data (ToUTF8::FromType encoding, VFS::Manager* vfs, ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir) +CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths, + const std::vector& archives, const Fallback::Map* fallback, const boost::filesystem::path& resDir) : mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), - mVFS(vfs), mResourcesManager (resourcesManager), mFallbackMap(fallback), - mReader (0), mDialogue (0), mReaderIndex(1), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS())) + mFallbackMap(fallback), mReader (0), mDialogue (0), mReaderIndex(1), + mFsStrict(fsStrict), mDataPaths(dataPaths), mArchives(archives) { + mVFS.reset(new VFS::Manager(mFsStrict)); + VFS::registerArchives(mVFS.get(), Files::Collections(mDataPaths, !mFsStrict), mArchives, true); + + mResourcesManager.setVFS(mVFS.get()); + mResourceSystem.reset(new Resource::ResourceSystem(mVFS.get())); + mResourceSystem->getSceneManager()->setShaderPath((resDir / "shaders").string()); int index = 0; @@ -1218,7 +1226,8 @@ std::vector CSMWorld::Data::getIds (bool listDeleted) const void CSMWorld::Data::assetsChanged() { - mVFS->rebuildIndex(); + mVFS.get()->reset(); + VFS::registerArchives(mVFS.get(), Files::Collections(mDataPaths, !mFsStrict), mArchives, true); const UniversalId assetTableIds[] = { UniversalId::Type_Meshes, @@ -1265,7 +1274,7 @@ void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end) const VFS::Manager* CSMWorld::Data::getVFS() const { - return mVFS; + return mVFS.get(); } const Fallback::Map* CSMWorld::Data::getFallbackMap() const diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 771a706b3..8a3667ea1 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -31,6 +31,7 @@ #include +#include #include #include "../doc/stage.hpp" @@ -46,6 +47,7 @@ #include "infocollection.hpp" #include "nestedinfocollection.hpp" #include "pathgrid.hpp" +#include "resourcesmanager.hpp" #include "metadata.hpp" #ifndef Q_MOC_RUN #include "subcellcollection.hpp" @@ -108,8 +110,6 @@ namespace CSMWorld RefCollection mRefs; IdCollection mFilters; Collection mMetaData; - VFS::Manager* mVFS; - ResourcesManager& mResourcesManager; const Fallback::Map* mFallbackMap; std::vector mModels; std::map mModelIndex; @@ -120,6 +120,11 @@ namespace CSMWorld std::map > mRefLoadCache; int mReaderIndex; + bool mFsStrict; + Files::PathContainer mDataPaths; + std::vector mArchives; + std::unique_ptr mVFS; + ResourcesManager mResourcesManager; std::shared_ptr mResourceSystem; std::vector > mReaders; @@ -141,7 +146,9 @@ namespace CSMWorld public: - Data (ToUTF8::FromType encoding, VFS::Manager* vfs, ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir); + Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths, + const std::vector& archives, const Fallback::Map* fallback, + const boost::filesystem::path& resDir); virtual ~Data(); diff --git a/components/vfs/archive.hpp b/components/vfs/archive.hpp index f2082f750..b36c7117b 100644 --- a/components/vfs/archive.hpp +++ b/components/vfs/archive.hpp @@ -21,9 +21,6 @@ namespace VFS public: virtual ~Archive() {} - /// Clears cached data. - virtual void reset() = 0; - /// List all resources contained in this archive, and run the resource names through the given normalize function. virtual void listResources(std::map& out, char (*normalize_function) (char)) = 0; }; diff --git a/components/vfs/bsaarchive.cpp b/components/vfs/bsaarchive.cpp index 88e6bf2c7..9b686049f 100644 --- a/components/vfs/bsaarchive.cpp +++ b/components/vfs/bsaarchive.cpp @@ -10,12 +10,6 @@ BsaArchive::BsaArchive(const std::string &filename) load(); } -void BsaArchive::reset() -{ - mResources.clear(); - load(); -} - void BsaArchive::listResources(std::map &out, char (*normalize_function)(char)) { for (std::vector::iterator it = mResources.begin(); it != mResources.end(); ++it) diff --git a/components/vfs/bsaarchive.hpp b/components/vfs/bsaarchive.hpp index 92204f90c..217594abd 100644 --- a/components/vfs/bsaarchive.hpp +++ b/components/vfs/bsaarchive.hpp @@ -24,8 +24,6 @@ namespace VFS public: BsaArchive(const std::string& filename); - virtual void reset(); - virtual void listResources(std::map& out, char (*normalize_function) (char)); private: diff --git a/components/vfs/filesystemarchive.cpp b/components/vfs/filesystemarchive.cpp index 8fb992e76..ad5150a44 100644 --- a/components/vfs/filesystemarchive.cpp +++ b/components/vfs/filesystemarchive.cpp @@ -12,12 +12,6 @@ namespace VFS } - void FileSystemArchive::reset() - { - mIndex.clear(); - mBuiltIndex = false; - } - void FileSystemArchive::listResources(std::map &out, char (*normalize_function)(char)) { if (!mBuiltIndex) diff --git a/components/vfs/filesystemarchive.hpp b/components/vfs/filesystemarchive.hpp index 5843bf871..6c8e1b82b 100644 --- a/components/vfs/filesystemarchive.hpp +++ b/components/vfs/filesystemarchive.hpp @@ -23,8 +23,6 @@ namespace VFS public: FileSystemArchive(const std::string& path); - virtual void reset(); - virtual void listResources(std::map& out, char (*normalize_function) (char)); diff --git a/components/vfs/manager.cpp b/components/vfs/manager.cpp index 9b1798e8f..4f3994bac 100644 --- a/components/vfs/manager.cpp +++ b/components/vfs/manager.cpp @@ -39,6 +39,12 @@ namespace VFS Manager::~Manager() { + reset(); + } + + void Manager::reset() + { + mIndex.clear(); for (std::vector::iterator it = mArchives.begin(); it != mArchives.end(); ++it) delete *it; mArchives.clear(); @@ -57,14 +63,6 @@ namespace VFS (*it)->listResources(mIndex, mStrict ? &strict_normalize_char : &nonstrict_normalize_char); } - void Manager::rebuildIndex() - { - for (std::vector::const_iterator it = mArchives.begin(); it != mArchives.end(); ++it) - (*it)->reset(); - - buildIndex(); - } - Files::IStreamPtr Manager::get(const std::string &name) const { std::string normalized = name; diff --git a/components/vfs/manager.hpp b/components/vfs/manager.hpp index 2ad7cf643..c5f0a8fec 100644 --- a/components/vfs/manager.hpp +++ b/components/vfs/manager.hpp @@ -26,6 +26,9 @@ namespace VFS ~Manager(); + // Empty the file index and unregister archives. + void reset(); + /// Register the given archive. All files contained in it will be added to the index on the next buildIndex() call. /// @note Takes ownership of the given pointer. void addArchive(Archive* archive); @@ -33,9 +36,6 @@ namespace VFS /// Build the file index. Should be called when all archives have been registered. void buildIndex(); - /// Rebuild the file index. New/deleted files (actual files, not bsa's) will be reflected. - void rebuildIndex(); - /// Does a file with this name exist? /// @note May be called from any thread once the index has been built. bool exists(const std::string& name) const; From d3d04171f9f1c80cfce59ed99a3e66da8fa57770 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Tue, 22 Aug 2017 15:06:56 -0400 Subject: [PATCH 12/12] Fix seg fault, undo changes BsaArchive --- apps/opencs/view/render/cell.cpp | 3 ++- components/vfs/bsaarchive.cpp | 20 +++++++------------- components/vfs/bsaarchive.hpp | 3 --- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index a10e38397..153de773c 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -297,7 +297,8 @@ void CSVRender::Cell::reloadAssets() mTerrain->loadCell(mCoordinates.getX(), mCoordinates.getY()); } - mCellWater->reloadAssets(); + if (mCellWater) + mCellWater->reloadAssets(); } void CSVRender::Cell::setSelection (int elementMask, Selection mode) diff --git a/components/vfs/bsaarchive.cpp b/components/vfs/bsaarchive.cpp index 9b686049f..a527a6ad9 100644 --- a/components/vfs/bsaarchive.cpp +++ b/components/vfs/bsaarchive.cpp @@ -5,9 +5,14 @@ namespace VFS BsaArchive::BsaArchive(const std::string &filename) - : mFileName(filename) { - load(); + mFile.open(filename); + + const Bsa::BSAFile::FileList &filelist = mFile.getList(); + for(Bsa::BSAFile::FileList::const_iterator it = filelist.begin();it != filelist.end();++it) + { + mResources.push_back(BsaArchiveFile(&*it, &mFile)); + } } void BsaArchive::listResources(std::map &out, char (*normalize_function)(char)) @@ -21,17 +26,6 @@ void BsaArchive::listResources(std::map &out, char (*normal } } -void BsaArchive::load() -{ - mFile.open(mFileName); - - const Bsa::BSAFile::FileList &filelist = mFile.getList(); - for(Bsa::BSAFile::FileList::const_iterator it = filelist.begin();it != filelist.end();++it) - { - mResources.push_back(BsaArchiveFile(&*it, &mFile)); - } -} - // ------------------------------------------------------------------------------ BsaArchiveFile::BsaArchiveFile(const Bsa::BSAFile::FileStruct *info, Bsa::BSAFile* bsa) diff --git a/components/vfs/bsaarchive.hpp b/components/vfs/bsaarchive.hpp index 217594abd..a6e274037 100644 --- a/components/vfs/bsaarchive.hpp +++ b/components/vfs/bsaarchive.hpp @@ -27,9 +27,6 @@ namespace VFS virtual void listResources(std::map& out, char (*normalize_function) (char)); private: - void load(); - - std::string mFileName; Bsa::BSAFile mFile; std::vector mResources;