Sun, 22 Dec 2013 20:44:46 +0200
- documents are now refcounted. This should seriously stabilize (and speed up!) the pruning of unused files
ldforge.pro | file | annotate | diff | comparison | revisions | |
src/document.cc | file | annotate | diff | comparison | revisions | |
src/document.h | file | annotate | diff | comparison | revisions | |
src/ldtypes.cc | file | annotate | diff | comparison | revisions | |
src/ldtypes.h | file | annotate | diff | comparison | revisions | |
src/misc.cc | file | annotate | diff | comparison | revisions | |
src/misc.h | file | annotate | diff | comparison | revisions | |
src/property.h | file | annotate | diff | comparison | revisions |
--- a/ldforge.pro Sat Dec 21 02:21:07 2013 +0200 +++ b/ldforge.pro Sun Dec 22 20:44:46 2013 +0200 @@ -16,7 +16,7 @@ RCC_DIR = ./build_shared/ UI_DIR = ./build_shared/ SOURCES = src/*.cc -HEADERS = src/*.h +HEADERS = src/*.h src/misc/*.h FORMS = ui/*.ui QT += opengl network QMAKE_CXXFLAGS += -std=c++0x
--- a/src/document.cc Sat Dec 21 02:21:07 2013 +0200 +++ b/src/document.cc Sun Dec 22 20:44:46 2013 +0200 @@ -14,11 +14,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. - * ===================================================================== - * - * file.cpp: File I/O and management. - * - File loading, parsing, manipulation, saving, closing. - * - LDraw path verification. */ #include <QMessageBox> @@ -43,8 +38,8 @@ static bool g_loadingMainFile = false; static const int g_maxRecentFiles = 10; static bool g_aborted = false; -static LDDocument* g_logoedStud = null; -static LDDocument* g_logoedStud2 = null; +static LDDocumentPointer g_logoedStud = null; +static LDDocumentPointer g_logoedStud2 = null; LDDocument* LDDocument::m_curdoc = null; @@ -113,8 +108,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- LDDocument::LDDocument() -{ setBeingDeleted (false); - setImplicit (true); +{ setImplicit (true); setSavePosition (-1); setListItem (null); setHistory (new History); @@ -128,7 +122,6 @@ // a ton of other functions will think this file is still valid when it is not! g_loadedFiles.removeOne (this); - setBeingDeleted (true); m_History->setIgnoring (true); // Clear everything from the model @@ -165,7 +158,6 @@ elif (this == g_logoedStud2) g_logoedStud2 = null; - closeUnused(); g_win->updateDocumentList(); log ("Closed %1", getName()); } @@ -912,9 +904,6 @@ if (obj->getType() == LDObject::Error) obj->replace (parseLine (static_cast<LDError*> (obj)->contents)); } - - // Close all files left unused - LDDocument::closeUnused(); } // ============================================================================= @@ -999,63 +988,12 @@ } // ============================================================================= -// ----------------------------------------------------------------------------- -static void getFilesUsed (LDDocument* node, QList<LDDocument*>& filesUsed) -{ filesUsed << node; - - for (LDObject* obj : node->getObjects()) - { if (obj->getType() != LDObject::Subfile) - continue; - - LDSubfile* ref = static_cast<LDSubfile*> (obj); - filesUsed << ref->getFileInfo(); - getFilesUsed (ref->getFileInfo(), filesUsed); - } -} - -// ============================================================================= -// Find out which files are unused and close them. -// ----------------------------------------------------------------------------- -static bool g_closingUnusedFiles = false; - -static void reallyCloseUnused() -{ // Don't go here more than once at a time, otherwise we risk double-deletions - if (g_closingUnusedFiles) - return; - - QList<LDDocument*> filesUsed; - g_closingUnusedFiles = true; - - // Anything that's explicitly opened must not be closed. - // Also do not close anything used by anything explicit - for (LDDocument* file : g_loadedFiles) - if (!file->isImplicit()) - getFilesUsed (file, filesUsed); - - // Savor the logoed studs if we use them - if (gl_logostuds && g_logoedStud && g_logoedStud2) - { getFilesUsed (g_logoedStud, filesUsed); - getFilesUsed (g_logoedStud2, filesUsed); - } - - // Remove duplicated entries - removeDuplicates (filesUsed); - - // Close all open files that aren't in filesUsed - for (LDDocument* file : g_loadedFiles) - if (!filesUsed.contains (file)) - delete file; - - g_closingUnusedFiles = false; -} - -// ============================================================================= +// Close all implicit files with no references // ----------------------------------------------------------------------------- void LDDocument::closeUnused() -{ // Close unused files later on in the event loop. This function sees a lot of - // calls, this reduces the amount of unneeded calls and prevents the engine - // from beginning to close unused files when it really shouldn't be doing that. - invokeLater (reallyCloseUnused); +{ for (LDDocument* file : g_loadedFiles) + if (file->isImplicit() && file->numReferences() == 0) + delete file; } // ============================================================================= @@ -1290,4 +1228,19 @@ shortname.prepend (topdirname + "\\"); return shortname; +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +void LDDocument::addReference (LDDocumentPointer* ptr) +{ m_refs << ptr; +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +void LDDocument::removeReference (LDDocumentPointer* ptr) +{ m_refs.removeOne (ptr); + + if (m_refs.size() == 0) + invokeLater (closeUnused); } \ No newline at end of file
--- a/src/document.h Sat Dec 21 02:21:07 2013 +0200 +++ b/src/document.h Sun Dec 22 20:44:46 2013 +0200 @@ -26,6 +26,7 @@ class History; class OpenProgressDialog; +class LDDocumentPointer; namespace LDPaths { void initPaths(); @@ -62,8 +63,7 @@ PROPERTY (public, bool, Implicit, BOOL_OPS, STOCK_WRITE) PROPERTY (public, QList<LDObject*>, Cache, NO_OPS, STOCK_WRITE) PROPERTY (public, long, SavePosition, NUM_OPS, STOCK_WRITE) - PROPERTY (public, QListWidgetItem*, ListItem, NO_OPS, STOCK_WRITE) - PROPERTY (private, bool, BeingDeleted, BOOL_OPS, STOCK_WRITE) + PROPERTY (public, QListWidgetItem*, ListItem, NO_OPS, STOCK_WRITE) public: LDDocument(); @@ -84,6 +84,9 @@ void swapObjects (LDObject* one, LDObject* other); bool isSafeToClose(); // Perform safety checks. Do this before closing any files! void setObject (int idx, LDObject* obj); + void addReference (LDDocumentPointer* ptr); + void removeReference (LDDocumentPointer* ptr); + int numReferences() const { return m_refs.size(); } inline LDDocument& operator<< (LDObject* obj) { addObject (obj); @@ -125,9 +128,10 @@ friend class LDObject; private: - QList<LDObject*> m_sel; + QList<LDObject*> m_sel; + QList<LDDocumentPointer*> m_refs; - static LDDocument* m_curdoc; + static LDDocument* m_curdoc; }; inline LDDocument* getCurrentDocument()
--- a/src/ldtypes.cc Sat Dec 21 02:21:07 2013 +0200 +++ b/src/ldtypes.cc Sun Dec 22 20:44:46 2013 +0200 @@ -263,10 +263,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- -LDSubfile::~LDSubfile() -{ // The document this subfile referenced may be unused now, delete if needed. - LDDocument::closeUnused(); -} +LDSubfile::~LDSubfile() {} // ============================================================================= // -----------------------------------------------------------------------------
--- a/src/ldtypes.h Sat Dec 21 02:21:07 2013 +0200 +++ b/src/ldtypes.h Sun Dec 22 20:44:46 2013 +0200 @@ -21,6 +21,7 @@ #include "main.h" #include "types.h" +#include "misc/documentPointer.h" #define LDOBJ(T) \ protected: \ @@ -377,7 +378,7 @@ LDOBJ_COLORED LDOBJ_SCEMANTIC LDOBJ_HAS_MATRIX - PROPERTY (public, LDDocument*, FileInfo, NO_OPS, STOCK_WRITE) + PROPERTY (public, LDDocumentPointer, FileInfo, NO_OPS, STOCK_WRITE) public: enum InlineFlag
--- a/src/misc.cc Sat Dec 21 02:21:07 2013 +0200 +++ b/src/misc.cc Sun Dec 22 20:44:46 2013 +0200 @@ -23,9 +23,12 @@ #include "misc.h" #include "gui.h" #include "dialogs.h" +#include "document.h" #include "ui_rotpoint.h" #include "moc_misc.cpp" +#include "misc/documentPointer.cc" + RingFinder g_RingFinder; // Prime number table.
--- a/src/misc.h Sat Dec 21 02:21:07 2013 +0200 +++ b/src/misc.h Sun Dec 22 20:44:46 2013 +0200 @@ -26,6 +26,7 @@ #define NUM_PRIMES 500 +class LDDocument; class QColor; class QAction;
--- a/src/property.h Sat Dec 21 02:21:07 2013 +0200 +++ b/src/property.h Sun Dec 22 20:44:46 2013 +0200 @@ -94,6 +94,12 @@ set##NAME( tmp ); \ } \ \ + void removeFrom##NAME( const TYPE::value_type& a ) \ + { TYPE tmp( m_##NAME ); \ + tmp.removeOne( a ); \ + set##NAME( tmp ); \ + } \ + \ inline void clear##NAME() \ { set##NAME( TYPE() ); \ }