# HG changeset patch # User Santeri Piippo # Date 1387381471 -7200 # Node ID 39085791128f4154d8a6853888f2c99f0b5dacde # Parent 5a31f6c14451dec95fae7446583035d696bd249e - corrected history behavior. LDObject::clone() is now off-limits, createCopy() must be used instead. LDObject::deleteSelf() must be used to delete LDObjects (destructor is protected now) diff -r 5a31f6c14451 -r 39085791128f src/addObjectDialog.cc --- a/src/addObjectDialog.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/addObjectDialog.cc Wed Dec 18 17:44:31 2013 +0200 @@ -243,7 +243,7 @@ setWindowTitle (fmt (tr ("Edit %1"), typeName)); setWindowIcon (icon); - delete defaults; + defaults->deleteSelf(); } // ============================================================================= diff -r 5a31f6c14451 -r 39085791128f src/document.cc --- a/src/document.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/document.cc Wed Dec 18 17:44:31 2013 +0200 @@ -125,11 +125,11 @@ LDDocument::~LDDocument() { // Clear everything from the model for (LDObject* obj : getObjects()) - delete obj; + obj->deleteSelf(); // Clear the cache as well for (LDObject* obj : getCache()) - delete obj; + obj->deleteSelf(); delete m_History; @@ -284,7 +284,7 @@ { // User wishes to abort, so stop here now. if (isAborted()) { for (LDObject* obj : m_Objects) - delete obj; + obj->deleteSelf(); m_Objects.clear(); setDone (true); @@ -870,6 +870,11 @@ if (obj->getType() == LDObject::Vertex) m_Vertices << obj; +#ifdef DEBUG + if (!isImplicit()) + dlog ("Added object #%1\n", obj->getID()); +#endif + obj->setFile (this); return getObjectCount() - 1; } @@ -877,7 +882,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- void LDDocument::addObjects (const QList objs) -{ for (LDObject * obj : objs) +{ for (LDObject* obj : objs) if (obj) addObject (obj); } @@ -894,6 +899,8 @@ // ----------------------------------------------------------------------------- void LDDocument::forgetObject (LDObject* obj) { int idx = obj->getIndex(); + assert (m_Objects[idx] == obj); + dlog ("id: %1, type: %2, code: %3", obj->getID(), obj->getType(), obj->raw()); getHistory()->add (new DelHistory (idx, obj)); m_Objects.removeAt (idx); obj->setFile (null); @@ -1015,9 +1022,8 @@ if (gl_logostuds && (flags & LDSubfile::RendererInline)) { if (getName() == "stud.dat" && g_logoedStud) return g_logoedStud->inlineContents (flags); - elif (getName() == "stud2.dat" && g_logoedStud2) - return g_logoedStud2->inlineContents (flags); + return g_logoedStud2->inlineContents (flags); } QList objs, objcache; @@ -1025,10 +1031,10 @@ bool deep = flags & LDSubfile::DeepInline, doCache = flags & LDSubfile::CacheInline; - // If we have this cached, just clone that + // If we have this cached, just create a copy of that if (deep && getCache().size()) { for (LDObject* obj : getCache()) - objs << obj->clone(); + objs << obj->createCopy(); } else { if (!deep) @@ -1049,19 +1055,19 @@ // flag when recursing deeper in hierarchy. QList otherobjs = ref->inlineContents (flags & ~ (LDSubfile::CacheInline)); - for (LDObject * otherobj : otherobjs) + for (LDObject* otherobj : otherobjs) { // Cache this object, if desired if (doCache) - objcache << otherobj->clone(); + objcache << otherobj->createCopy(); objs << otherobj; } } else { if (doCache) - objcache << obj->clone(); + objcache << obj->createCopy(); - objs << obj->clone(); + objs << obj->createCopy(); } } diff -r 5a31f6c14451 -r 39085791128f src/extprogs.cc --- a/src/extprogs.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/extprogs.cc Wed Dec 18 17:44:31 2013 +0200 @@ -157,7 +157,7 @@ writeObjects (objs, f); for (LDObject* obj : objs) - delete obj; + obj->deleteSelf(); } else f.write (obj->raw() + "\r\n"); @@ -282,7 +282,7 @@ for (LDObject * obj : objs) { if (!obj->isScemantic()) - { delete obj; + { obj->deleteSelf(); continue; } diff -r 5a31f6c14451 -r 39085791128f src/gldraw.cc --- a/src/gldraw.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/gldraw.cc Wed Dec 18 17:44:31 2013 +0200 @@ -858,12 +858,11 @@ switch (obj->getType()) { case LDObject::Line: - compileSubObject (obj, GL_LINES); - break; + { compileSubObject (obj, GL_LINES); + } break; case LDObject::CondLine: - - // Draw conditional lines with a dash pattern - however, use a full + { // Draw conditional lines with a dash pattern - however, use a full // line when drawing a pick list to make selecting them easier. if (list != GL::PickList) { glLineStipple (1, 0x6666); @@ -873,15 +872,15 @@ compileSubObject (obj, GL_LINES); glDisable (GL_LINE_STIPPLE); - break; + } break; case LDObject::Triangle: - compileSubObject (obj, GL_TRIANGLES); - break; + { compileSubObject (obj, GL_TRIANGLES); + } break; case LDObject::Quad: - compileSubObject (obj, GL_QUADS); - break; + { compileSubObject (obj, GL_QUADS); + } break; case LDObject::Subfile: { LDSubfile* ref = static_cast (obj); @@ -901,14 +900,13 @@ if (prev && prev->getType() == LDObject::BFC && static_cast (prev)->type == LDBFC::InvertNext) g_glInvert = !g_glInvert; - for (LDObject * obj : objs) + for (LDObject* obj : objs) { compileList (obj, list); - delete obj; + obj->deleteSelf(); } g_glInvert = oldinvert; - } - break; + } break; default: break; @@ -1250,6 +1248,7 @@ if (idx == 0xFFFFFF) continue; // White is background; skip + dlog ("idx: %1", idx); LDObject* obj = LDObject::fromID (idx); // If this is an additive single pick and the object is currently selected, @@ -1557,7 +1556,7 @@ for (LDObject* obj : objs) { verts << getVertices (obj); - delete obj; + obj->deleteSelf(); } } @@ -1587,7 +1586,7 @@ m_knownVerts << verts; removeDuplicates (m_knownVerts); - obj->m_glinit = true; + obj->setGLInit (true); } // ============================================================================= @@ -1627,13 +1626,13 @@ // ----------------------------------------------------------------------------- void GLRenderer::deleteLists (LDObject* obj) { // Delete the lists but only if they have been initialized - if (!obj->m_glinit) + if (!obj->isGLInit()) return; -for (const GL::ListType listType : g_glListTypes) + for (const GL::ListType listType : g_glListTypes) glDeleteLists (obj->glLists[listType], 1); - obj->m_glinit = false; + obj->setGLInit (false); } // ============================================================================= @@ -1890,7 +1889,7 @@ LDOverlay* GLRenderer::findOverlayObject (EFixedCamera cam) { LDOverlay* ovlobj = null; - for (LDObject * obj : getFile()->getObjects()) + for (LDObject* obj : getFile()->getObjects()) { if (obj->getType() == LDObject::Overlay && static_cast (obj)->getCamera() == cam) { ovlobj = static_cast (obj); break; @@ -1936,14 +1935,11 @@ LDObject* nextobj = ovlobj->next(); if (nextobj && nextobj->getType() == LDObject::Empty) - { getFile()->forgetObject (nextobj); - delete nextobj; - } + nextobj->deleteSelf(); // If the overlay object was there and the overlay itself is // not, remove the object. - getFile()->forgetObject (ovlobj); - delete ovlobj; + ovlobj->deleteSelf(); } elif (meta.img && !ovlobj) { // Inverse case: image is there but the overlay object is // not, thus create the object. diff -r 5a31f6c14451 -r 39085791128f src/gui.cc --- a/src/gui.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/gui.cc Wed Dec 18 17:44:31 2013 +0200 @@ -266,7 +266,7 @@ // Delete the objects that were being selected for (LDObject* obj : selCopy) - delete obj; + obj->deleteSelf(); refresh(); return selCopy.size(); @@ -540,7 +540,7 @@ LDObject::Type ForgeWindow::getUniformSelectedType() { LDObject::Type result = LDObject::Unidentified; - for (LDObject * obj : selection()) + for (LDObject* obj : selection()) { if (result != LDObject::Unidentified && obj->getColor() != result) return LDObject::Unidentified; @@ -606,12 +606,11 @@ } // ============================================================================= +// TODO: what the heh? // ----------------------------------------------------------------------------- void ForgeWindow::deleteObjects (QList objs) -{ for (LDObject * obj : objs) - { getCurrentDocument()->forgetObject (obj); - delete obj; - } +{ for (LDObject* obj : objs) + obj->deleteSelf(); } // ============================================================================= @@ -785,7 +784,7 @@ void makeColorComboBox (QComboBox* box) { std::map counts; - for (LDObject * obj : getCurrentDocument()->getObjects()) + for (LDObject* obj : getCurrentDocument()->getObjects()) { if (!obj->isColored()) continue; @@ -908,7 +907,7 @@ ui->objectList->clear(); LDDocument* f = getCurrentDocument(); -for (LDObject * obj : *f) +for (LDObject* obj : *f) ui->objectList->addItem (obj->qObjListEntry); #endif diff -r 5a31f6c14451 -r 39085791128f src/gui_editactions.cc --- a/src/gui_editactions.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/gui_editactions.cc Wed Dec 18 17:44:31 2013 +0200 @@ -132,8 +132,7 @@ // Merge in the inlined objects for (LDObject * inlineobj : objs) { str line = inlineobj->raw(); - delete inlineobj; - + inlineobj->deleteSelf(); LDObject* newobj = parseLine (line); getCurrentDocument()->insertObj (idx++, newobj); newobj->select(); @@ -141,8 +140,7 @@ } // Delete the subfile now as it's been inlined. - getCurrentDocument()->forgetObject (obj); - delete obj; + obj->deleteSelf(); } g_win->refresh(); @@ -183,7 +181,7 @@ g_win->R()->compileObject (t); // Delete this quad now, it has been split. - delete obj; + obj->deleteSelf(); num++; } diff -r 5a31f6c14451 -r 39085791128f src/history.cc --- a/src/history.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/history.cc Wed Dec 18 17:44:31 2013 +0200 @@ -38,10 +38,14 @@ const Changeset& set = getChangeset (getPosition()); g_fullRefresh = false; + dlog ("History: performing undo: set has %1 changes", set.size()); // Iterate the list in reverse and undo all actions - for (auto it = set.end() - 1; it != set.begin(); --it) - (*it)->undo(); + for (int i = set.size() - 1; i >= 0; --i) + { AbstractHistoryEntry* change = set[i]; + dlog ("Undo change of type %1", change->getType()); + change->undo(); + } decreasePosition(); @@ -56,7 +60,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- void History::redo() -{ if (getPosition() == (long) m_changesets.size()) +{ if (getPosition() == m_changesets.size()) return; const Changeset& set = getChangeset (getPosition() + 1); @@ -84,6 +88,7 @@ delete change; m_changesets.clear(); + dlog ("History: cleared"); } // ============================================================================= @@ -93,8 +98,15 @@ return; while (getPosition() < getSize() - 1) + { Changeset last = m_changesets.last(); + + for (AbstractHistoryEntry* entry : last) + delete entry; + m_changesets.removeLast(); + } + dlog ("History: step added (%1 changes)", m_currentChangeset.size()); m_changesets << m_currentChangeset; m_currentChangeset.clear(); setPosition (getPosition() + 1); @@ -111,35 +123,43 @@ entry->setParent (this); m_currentChangeset << entry; + dlog ("History: added entry of type %1", entry->getTypeName()); } // ============================================================================= // ----------------------------------------------------------------------------- void AddHistory::undo() const -{ LDDocument* f = getParent()->getFile(); - LDObject* obj = f->getObject (getIndex()); - f->forgetObject (obj); - delete obj; - +{ LDObject* obj = getParent()->getFile()->getObject (getIndex()); + dlog ("History: undoing addition of #%1", obj->getID()); + obj->deleteSelf(); g_fullRefresh = true; } // ============================================================================= // ----------------------------------------------------------------------------- void AddHistory::redo() const -{ LDDocument* f = getParent()->getFile(); - LDObject* obj = parseLine (getCode()); - f->insertObj (getIndex(), obj); +{ LDObject* obj = parseLine (getCode()); + getParent()->getFile()->insertObj (getIndex(), obj); g_win->R()->compileObject (obj); } // ============================================================================= +// ----------------------------------------------------------------------------- +DelHistory::DelHistory (int idx, LDObject* obj) +{ dlog ("obj is: %1, code: %2", obj->getType(), obj->raw()); + setIndex (idx); + setCode (obj->raw()); +} + +// ============================================================================= // heh // ----------------------------------------------------------------------------- void DelHistory::undo() const -{ LDDocument* f = getParent()->getFile(); +{ dlog ("code: %1", getCode()); + dlog ("index: %1", getIndex()); LDObject* obj = parseLine (getCode()); - f->insertObj (getIndex(), obj); + dlog( "new obj is of type %1 (%2)\n", obj->getType(), obj->getTypeName() ); + getParent()->getFile()->insertObj (getIndex(), obj); g_win->R()->compileObject (obj); } @@ -148,8 +168,7 @@ void DelHistory::redo() const { LDDocument* f = getParent()->getFile(); LDObject* obj = f->getObject (getIndex()); - f->forgetObject (obj); - delete obj; + obj->deleteSelf(); g_fullRefresh = true; } diff -r 5a31f6c14451 -r 39085791128f src/history.h --- a/src/history.h Wed Dec 18 17:03:35 2013 +0200 +++ b/src/history.h Wed Dec 18 17:44:31 2013 +0200 @@ -26,15 +26,16 @@ virtual ~N##History(){} \ virtual void undo() const override; \ virtual void redo() const override; \ - virtual History::Type getType() const override { return History::N; } + virtual History::Type getType() const override { return History::N; } \ + virtual const char* getTypeName() const { return #N; } class AbstractHistoryEntry; // ============================================================================= class History -{ PROPERTY (private, long, Position, NUM_OPS, STOCK_WRITE) +{ PROPERTY (private, int, Position, NUM_OPS, STOCK_WRITE) PROPERTY (public, LDDocument*, File, NO_OPS, STOCK_WRITE) - PROPERTY (public, bool, Ignoring, BOOL_OPS, STOCK_WRITE) + PROPERTY (public, bool, Ignoring, BOOL_OPS, STOCK_WRITE) public: typedef QList Changeset; @@ -83,9 +84,14 @@ virtual ~AbstractHistoryEntry() {} virtual void undo() const {} virtual void redo() const {} + virtual History::Type getType() const { return (History::Type) 0; } + + virtual const char* getTypeName() const + { return ""; + } }; // ============================================================================= @@ -97,10 +103,7 @@ public: IMPLEMENT_HISTORY_TYPE (Del) - - DelHistory (int idx, LDObject* obj) : - m_Index (idx), - m_Code (obj->raw()) {} + DelHistory (int idx, LDObject* obj); }; // ============================================================================= diff -r 5a31f6c14451 -r 39085791128f src/ldtypes.cc --- a/src/ldtypes.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/ldtypes.cc Wed Dec 18 17:44:31 2013 +0200 @@ -40,20 +40,23 @@ m_Selected (false), m_Parent (null), m_File (null), - qObjListEntry (null), - m_glinit (false) -{ - memset (m_coords, 0, sizeof m_coords); + m_GLInit (false), + qObjListEntry (null) +{ memset (m_coords, 0, sizeof m_coords); + chooseID(); + g_LDObjects << this; +} - // Determine ID - int32 id = 1; // 0 is invalid +// ============================================================================= +// ----------------------------------------------------------------------------- +void LDObject::chooseID() +{ int32 id = 1; // 0 is invalid for (LDObject* obj : g_LDObjects) if (obj->getID() >= id) id = obj->getID() + 1; setID (id); - g_LDObjects << this; } // ============================================================================= @@ -97,13 +100,13 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDComment::raw() +str LDComment::raw() const { return fmt ("0 %1", text); } // ============================================================================= // ----------------------------------------------------------------------------- -str LDSubfile::raw() +str LDSubfile::raw() const { str val = fmt ("1 %1 %2 ", getColor(), getPosition()); val += getTransform().stringRep(); val += ' '; @@ -113,7 +116,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDLine::raw() +str LDLine::raw() const { str val = fmt ("2 %1", getColor()); for (int i = 0; i < 2; ++i) @@ -124,7 +127,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDTriangle::raw() +str LDTriangle::raw() const { str val = fmt ("3 %1", getColor()); for (int i = 0; i < 3; ++i) @@ -135,7 +138,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDQuad::raw() +str LDQuad::raw() const { str val = fmt ("4 %1", getColor()); for (int i = 0; i < 4; ++i) @@ -146,7 +149,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDCondLine::raw() +str LDCondLine::raw() const { str val = fmt ("5 %1", getColor()); // Add the coordinates @@ -158,19 +161,19 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDError::raw() +str LDError::raw() const { return contents; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDVertex::raw() +str LDVertex::raw() const { return fmt ("0 !LDFORGE VERTEX %1 %2", getColor(), pos); } // ============================================================================= // ----------------------------------------------------------------------------- -str LDEmpty::raw() +str LDEmpty::raw() const { return ""; } @@ -189,7 +192,7 @@ "NOCLIP", }; -str LDBFC::raw() +str LDBFC::raw() const { return fmt ("0 BFC %1", LDBFC::statements[type]); } @@ -263,8 +266,14 @@ // ============================================================================= // ----------------------------------------------------------------------------- -LDObject::~LDObject() -{ // If this object was selected, unselect it now +LDObject::~LDObject() {} + +// ============================================================================= +// ----------------------------------------------------------------------------- +void LDObject::deleteSelf() +{ dlog( "#%1: type: %2\n", getID(), getType()); + + // If this object was selected, unselect it now if (isSelected()) unselect(); @@ -277,6 +286,8 @@ // Remove this object from the list of LDObjects g_LDObjects.removeOne (this); + + delete this; } // ============================================================================= @@ -321,8 +332,8 @@ { QList objs = getFileInfo()->inlineContents (flags); // Transform the objects -for (LDObject * obj : objs) - { // Set the parent now so we know what inlined this. + for (LDObject* obj : objs) + { // Set the parent now so we know what inlined the object. obj->setParent (this); transformObject (obj, getTransform(), getPosition(), getColor()); } @@ -333,10 +344,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- long LDObject::getIndex() const -{ -#ifndef RELEASE - assert (getFile() != null); -#endif +{ assert (getFile() != null); for (int i = 0; i < getFile()->getObjectCount(); ++i) if (getFile()->getObject (i) == this) @@ -556,8 +564,7 @@ if (bfc && bfc->type == LDBFC::InvertNext) { // This is prefixed with an invertnext, thus remove it. - getFile()->forgetObject (bfc); - delete bfc; + bfc->deleteSelf(); return; } } @@ -613,7 +620,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDOverlay::raw() +str LDOverlay::raw() const { return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", getFileName(), getCamera(), getX(), getY(), getWidth(), getHeight()); } @@ -636,7 +643,8 @@ *ptr = val; str after = obj->raw(); - obj->getFile()->addToHistory (new EditHistory (idx, before, after)); + if (before != after) + obj->getFile()->addToHistory (new EditHistory (idx, before, after)); } else *ptr = val; @@ -713,6 +721,7 @@ return; } + dlog ("Selected #%1\n", getID()); getFile()->addToSelection (this); } @@ -743,4 +752,44 @@ assert (false); return ""; +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +LDObject* LDObject::createCopy() const +{ /* + LDObject* copy = clone(); + copy->setFile (null); + copy->setGLInit (false); + copy->chooseID(); + copy->setSelected (false); + */ + + /* + LDObject* copy = getDefault (getType()); + copy->setColor (getColor()); + + if (hasMatrix()) + { LDMatrixObject* copyMo = static_cast (copy); + const LDMatrixObject* mo = static_cast (this); + copyMo->setPosition (mo->getPosition()); + copyMo->setTransform (mo->getTransform()); + } + else + { for (int i = 0; i < vertices(); ++i) + copy->setVertex (getVertex (i)); + } + + switch (getType()) + { case Subfile: + { LDSubfile* copyRef = static_cast (copy); + const LDSubfile* ref = static_cast (this); + + copyRef->setFileInfo (ref->getFileInfo()); + } + } + */ + + LDObject* copy = parseLine (raw()); + return copy; } \ No newline at end of file diff -r 5a31f6c14451 -r 39085791128f src/ldtypes.h --- a/src/ldtypes.h Wed Dec 18 17:03:35 2013 +0200 +++ b/src/ldtypes.h Wed Dec 18 17:44:31 2013 +0200 @@ -23,16 +23,17 @@ #include "types.h" #define LDOBJ(T) \ +protected: \ + virtual ~LD##T() {} \ + virtual LD##T* clone() override { \ + return new LD##T (*this); \ + } \ public: \ - virtual ~LD##T() {} \ virtual LDObject::Type getType() const override { \ return LDObject::T; \ } \ - virtual str raw(); \ - virtual LD##T* clone() { \ - return new LD##T (*this); \ - } \ - virtual void invert(); + virtual str raw() const override; \ + virtual void invert() override; #define LDOBJ_NAME(N) virtual str getTypeName() const override { return #N; } #define LDOBJ_VERTICES(V) virtual int vertices() const override { return V; } @@ -62,12 +63,13 @@ // sub-classes based on this enumerator. // ============================================================================= class LDObject -{ PROPERTY (public, bool, Hidden, BOOL_OPS, STOCK_WRITE) - PROPERTY (public, bool, Selected, BOOL_OPS, STOCK_WRITE) - PROPERTY (public, LDObject*, Parent, NO_OPS, STOCK_WRITE) - PROPERTY (public, LDDocument*, File, NO_OPS, STOCK_WRITE) - PROPERTY (private, int32, ID, NUM_OPS, STOCK_WRITE) - PROPERTY (public, int, Color, NUM_OPS, CUSTOM_WRITE) +{ PROPERTY (public, bool, Hidden, BOOL_OPS, STOCK_WRITE) + PROPERTY (public, bool, Selected, BOOL_OPS, STOCK_WRITE) + PROPERTY (public, LDObject*, Parent, NO_OPS, STOCK_WRITE) + PROPERTY (public, LDDocument*, File, NO_OPS, STOCK_WRITE) // TODO: rename~ + PROPERTY (private, int32, ID, NUM_OPS, STOCK_WRITE) + PROPERTY (public, int, Color, NUM_OPS, CUSTOM_WRITE) + PROPERTY (public, bool, GLInit, BOOL_OPS, STOCK_WRITE) public: // Object type codes. Codes are sorted in order of significance. @@ -76,7 +78,7 @@ Quad, // Object represents a quadrilateral Triangle, // Object represents a triangle Line, // Object represents a line - CondLine, // Object represents a conditional line + CondLine, // Object represents a conditional line Vertex, // Object is a vertex, LDForge extension object BFC, // Object represents a BFC statement Overlay, // Object contains meta-info about an overlay image. @@ -88,36 +90,85 @@ }; LDObject(); - virtual ~LDObject(); + + // Makes a copy of this object + LDObject* createCopy() const; + + // Deletes this object + void deleteSelf(); + + // Index (i.e. line number) of this object + long getIndex() const; + + // Type enumerator of this object + virtual LDObject::Type getType() const; + + // Get a vertex by index + const vertex& getVertex (int i) const; + + // Type name of this object + virtual str getTypeName() const; + + // Does this object have a matrix and position? (see LDMatrixObject) + virtual bool hasMatrix() const; + + // Inverts this object (winding is reversed) + virtual void invert(); + + // Is this object colored? + virtual bool isColored() const; + + // Does this object have meaning in the part model? + virtual bool isScemantic() const; + + // Moves this object using the given vertex as a movement List + void move (vertex vect); + + // Object after this in the current file + LDObject* next() const; + + // Object prior to this in the current file + LDObject* prev() const; - virtual LDObject* clone() - { return 0; // Creates a new LDObject identical to this one. - } - long getIndex() const; // Index (i.e. line number) of this object - virtual LDObject::Type getType() const; // Type enumerator of this object - const vertex& getVertex (int i) const; // Get a vertex by index - virtual str getTypeName() const; // Type name of this object - virtual bool hasMatrix() const; // Does this object have a matrix and position? (see LDMatrixObject) - virtual void invert(); // Inverts this object (winding is reversed) - virtual bool isColored() const; // Is this object colored? - virtual bool isScemantic() const; // Does this object have meaning in the part model? - void move (vertex vect); // Moves this object using the given vertex as a movement List - LDObject* next() const; // Object after this in the current file - LDObject* prev() const; // Object prior to this in the current file - virtual str raw() { return ""; } // This object as LDraw code - void replace (LDObject* other); // Replace this LDObject with another LDObject. Object is deleted in the process. - void select(); - void setVertex (int i, const vertex& vert); // Set a vertex to the given value - void setVertexCoord (int i, Axis ax, double value); // Set a single coordinate of a vertex - void swap (LDObject* other); // Swap this object with another. - LDObject* topLevelParent(); // What object in the current file ultimately references this? - void unselect(); - virtual int vertices() const; // Number of vertices this object has + // This object as LDraw code + virtual str raw() const = 0; + + // Replace this LDObject with another LDObject. Object is deleted in the process. + void replace (LDObject* other); + + // Selects this object. + void select(); + + // Set a vertex to the given value + void setVertex (int i, const vertex& vert); + + // Set a single coordinate of a vertex + void setVertexCoord (int i, Axis ax, double value); + + // Swap this object with another. + void swap (LDObject* other); - static str typeName (LDObject::Type type); // Get type name by enumerator - static LDObject* getDefault (const LDObject::Type type); // Returns a sample object by the given enumerator - static void moveObjects (QList objs, const bool up); // TODO: move this to LDDocument? - static str describeObjects (const QList& objs); // Get a description of a list of LDObjects + // What object in the current file ultimately references this? + LDObject* topLevelParent(); + + // Removes this object from selection // TODO: rename to deselect? + void unselect(); + + // Number of vertices this object has // TODO: rename to getNumVertices + virtual int vertices() const; + + // Get type name by enumerator + static str typeName (LDObject::Type type); + + // Returns a sample object by the given enumerator + // TODO: Use of this function only really results in hacks, get rid of it! + static LDObject* getDefault (const LDObject::Type type); + + // TODO: move this to LDDocument? + static void moveObjects (QList objs, const bool up); + + // Get a description of a list of LDObjects + static str describeObjects (const QList& objs); static LDObject* fromID (int id); // TODO: make these private! @@ -128,10 +179,17 @@ QListWidgetItem* qObjListEntry; protected: - bool m_glinit; - friend class GLRenderer; + // LDObjects are to be deleted with the deleteSelf() method, not with + // operator delete. This is because it seems virtual functions cannot + // be properly called from the destructor, thus a normal method must + // be used instead. The destructor also doesn't seem to be able to + // be private without causing a truckload of problems so it's protected + // instead. + virtual ~LDObject(); + void chooseID(); private: + virtual LDObject* clone() = 0; LDSharedVertex* m_coords[4]; }; @@ -338,7 +396,7 @@ } // Inlines this subfile. Note that return type is an array of heap-allocated - // LDObject-clones, they must be deleted one way or another. + // LDObject copies, they must be deleted manually. QList inlineContents (InlineFlags flags); }; diff -r 5a31f6c14451 -r 39085791128f src/main.h --- a/src/main.h Wed Dec 18 17:03:35 2013 +0200 +++ b/src/main.h Wed Dec 18 17:44:31 2013 +0200 @@ -100,6 +100,16 @@ #define FUNCNAME __func__ #endif // __GNUC__ +#ifdef IN_IDE_PARSER +void dlog(void, ...) {} +#else +# ifdef DEBUG +# define dlog(...) log( str( __PRETTY_FUNCTION__ ) + ": " __VA_ARGS__) +# else +# define dlog(...) +# endif // DEBUG +#endif // IN_IDE_PARSER + // Replace assert with a version that shows a GUI dialog if possible. // On Windows I just can't get the actual error messages otherwise. void assertionFailure (const char* file, int line, const char* funcname, const char* expr); diff -r 5a31f6c14451 -r 39085791128f src/types.cc --- a/src/types.cc Wed Dec 18 17:03:35 2013 +0200 +++ b/src/types.cc Wed Dec 18 17:44:31 2013 +0200 @@ -535,7 +535,7 @@ for (LDObject * obj : objs) { calcObject (obj); - delete obj; + obj->deleteSelf(); } } break;