src/ldObject.cc

changeset 943
af81220741d9
parent 920
147497785496
child 944
1a6f1997fcbe
equal deleted inserted replaced
920:147497785496 943:af81220741d9
30 CFGENTRY (String, DefaultName, "") 30 CFGENTRY (String, DefaultName, "")
31 CFGENTRY (String, DefaultUser, "") 31 CFGENTRY (String, DefaultUser, "")
32 CFGENTRY (Bool, UseCALicense, true) 32 CFGENTRY (Bool, UseCALicense, true)
33 33
34 // List of all LDObjects 34 // List of all LDObjects
35 QMap<long, LDObjectWeakPtr> g_allObjects; 35 QMap<int32, LDObjectWeakPtr> g_allObjects;
36 static int32 g_idcursor = 1; // 0 shalt be null 36 static int32 g_idcursor = 1; // 0 shalt be null
37 static constexpr int32 g_maxID = (1 << 24); 37
38 enum { MAX_LDOBJECT_IDS = (1 << 24) };
38 39
39 #define LDOBJ_DEFAULT_CTOR(T,BASE) \ 40 #define LDOBJ_DEFAULT_CTOR(T,BASE) \
40 T :: T (LDObjectPtr* selfptr) : \ 41 T :: T (LDDocument* document) : \
41 BASE (selfptr) {} 42 BASE (document) {}
42 43
43 // ============================================================================= 44 // =============================================================================
44 // LDObject constructors 45 // LDObject constructors
45 // 46 //
46 LDObject::LDObject (LDObjectPtr* selfptr) : 47 LDObject::LDObject (LDDocument* document) :
47 m_isHidden (false), 48 m_isHidden (false),
48 m_isSelected (false), 49 m_isSelected (false),
49 m_isDestructed (false), 50 m_isDestructed (false),
50 qObjListEntry (null) 51 qObjListEntry (null)
51 { 52 {
52 *selfptr = LDObjectPtr (this, [](LDObject* obj){ obj->finalDelete(); }); 53 if (document)
54 document->addObject (this);
55
53 memset (m_coords, 0, sizeof m_coords); 56 memset (m_coords, 0, sizeof m_coords);
54 m_self = selfptr->toWeakRef();
55 chooseID(); 57 chooseID();
56 g_allObjects[id()] = self(); 58
59 if (id() != 0)
60 g_allObjects[id()] = this;
61
57 setRandomColor (QColor::fromHsv (rand() % 360, rand() % 256, rand() % 96 + 128)); 62 setRandomColor (QColor::fromHsv (rand() % 360, rand() % 256, rand() % 96 + 128));
58 } 63 }
59 64
60 LDSubfile::LDSubfile (LDObjectPtr* selfptr) : 65 LDSubfile::LDSubfile (LDDocument* document) :
61 LDMatrixObject (selfptr) {} 66 LDMatrixObject (document) {}
62 67
63 LDOBJ_DEFAULT_CTOR (LDEmpty, LDObject) 68 LDOBJ_DEFAULT_CTOR (LDEmpty, LDObject)
64 LDOBJ_DEFAULT_CTOR (LDError, LDObject) 69 LDOBJ_DEFAULT_CTOR (LDError, LDObject)
65 LDOBJ_DEFAULT_CTOR (LDLine, LDObject) 70 LDOBJ_DEFAULT_CTOR (LDLine, LDObject)
66 LDOBJ_DEFAULT_CTOR (LDTriangle, LDObject) 71 LDOBJ_DEFAULT_CTOR (LDTriangle, LDObject)
73 78
74 // ============================================================================= 79 // =============================================================================
75 // 80 //
76 void LDObject::chooseID() 81 void LDObject::chooseID()
77 { 82 {
78 // If this is the first pass we can just use a global ID counter for each 83 // Let's hope that nobody goes to create 17 million objects anytime soon...
79 // unique object. Let's hope that nobody goes to create 17 million objects 84 if (g_idcursor < MAX_LDOBJECT_IDS)
80 // anytime soon.
81 if (g_idcursor < g_maxID)
82 {
83 setID (g_idcursor++); 85 setID (g_idcursor++);
84 return; 86 else
85 } 87 setID (0);
86
87 // In case someone does, we cannot really continue execution. We must abort,
88 // give the user a chance to save their documents though.
89 Critical ("Created too many objects. Execution cannot continue. You have a "
90 "chance to save any changes to documents, then restart.");
91 (void) IsSafeToCloseAll();
92 Exit();
93 } 88 }
94 89
95 // ============================================================================= 90 // =============================================================================
96 // 91 //
97 void LDObject::setVertexCoord (int i, Axis ax, double value) 92 void LDObject::setVertexCoord (int i, Axis ax, double value)
218 // 0---3 0---3 3 213 // 0---3 0---3 3
219 // | | | / /| 214 // | | | / /|
220 // | | ==> | / / | 215 // | | ==> | / / |
221 // | | |/ / | 216 // | | |/ / |
222 // 1---2 1 1---2 217 // 1---2 1 1---2
223 LDTrianglePtr tri1 (LDSpawn<LDTriangle> (vertex (0), vertex (1), vertex (3))); 218 LDTrianglePtr tri1 (new LDTriangle (vertex (0), vertex (1), vertex (3)));
224 LDTrianglePtr tri2 (LDSpawn<LDTriangle> (vertex (1), vertex (2), vertex (3))); 219 LDTrianglePtr tri2 (new LDTriangle (vertex (1), vertex (2), vertex (3)));
225 220
226 // The triangles also inherit the quad's color 221 // The triangles also inherit the quad's color
227 tri1->setColor (color()); 222 tri1->setColor (color());
228 tri2->setColor (color()); 223 tri2->setColor (color());
229 224
232 227
233 // ============================================================================= 228 // =============================================================================
234 // 229 //
235 void LDObject::replace (LDObjectPtr other) 230 void LDObject::replace (LDObjectPtr other)
236 { 231 {
237 long idx = lineNumber(); 232 int idx = lineNumber();
238 assert (idx != -1); 233
239 234 if (idx != -1)
240 // Replace the instance of the old object with the new object 235 {
241 document().toStrongRef()->setObject (idx, other); 236 // Replace the instance of the old object with the new object
242 237 document()->setObject (idx, other);
243 // Remove the old object 238
244 destroy(); 239 // Remove the old object
240 destroy();
241 }
245 } 242 }
246 243
247 // ============================================================================= 244 // =============================================================================
248 // 245 //
249 void LDObject::swap (LDObjectPtr other) 246 void LDObject::swap (LDObjectPtr other)
250 { 247 {
251 assert (document() == other->document()); 248 assert (document() == other->document());
252 document().toStrongRef()->swapObjects (self(), other); 249 document()->swapObjects (self(), other);
253 } 250 }
254 251
255 // ============================================================================= 252 // =============================================================================
256 // 253 //
257 LDLine::LDLine (LDObjectPtr* selfptr, Vertex v1, Vertex v2) : 254 LDLine::LDLine (Vertex v1, Vertex v2, LDDocument* document) :
258 LDObject (selfptr) 255 LDObject (document)
259 { 256 {
260 setVertex (0, v1); 257 setVertex (0, v1);
261 setVertex (1, v2); 258 setVertex (1, v2);
262 } 259 }
263 260
264 // ============================================================================= 261 // =============================================================================
265 // 262 //
266 LDTriangle::LDTriangle (LDObjectPtr* selfptr, const Vertex& v1, const Vertex& v2, const Vertex& v3) : 263 LDTriangle::LDTriangle (const Vertex& v1, const Vertex& v2, const Vertex& v3, LDDocument* document) :
267 LDObject (selfptr) 264 LDObject (document)
268 { 265 {
269 setVertex (0, v1); 266 setVertex (0, v1);
270 setVertex (1, v2); 267 setVertex (1, v2);
271 setVertex (2, v3); 268 setVertex (2, v3);
272 } 269 }
273 270
274 // ============================================================================= 271 // =============================================================================
275 // 272 //
276 LDQuad::LDQuad (LDObjectPtr* selfptr, const Vertex& v1, const Vertex& v2, 273 LDQuad::LDQuad (const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex& v4, LDDocument* document) :
277 const Vertex& v3, const Vertex& v4) : 274 LDObject (document)
278 LDObject (selfptr)
279 { 275 {
280 setVertex (0, v1); 276 setVertex (0, v1);
281 setVertex (1, v2); 277 setVertex (1, v2);
282 setVertex (2, v3); 278 setVertex (2, v3);
283 setVertex (3, v4); 279 setVertex (3, v4);
284 } 280 }
285 281
286 // ============================================================================= 282 // =============================================================================
287 // 283 //
288 LDCondLine::LDCondLine (LDObjectPtr* selfptr, const Vertex& v0, const Vertex& v1, 284 LDCondLine::LDCondLine (const Vertex& v0, const Vertex& v1, const Vertex& v2, const Vertex& v3, LDDocument* document) :
289 const Vertex& v2, const Vertex& v3) : 285 LDLine (document)
290 LDLine (selfptr)
291 { 286 {
292 setVertex (0, v0); 287 setVertex (0, v0);
293 setVertex (1, v1); 288 setVertex (1, v1);
294 setVertex (2, v2); 289 setVertex (2, v2);
295 setVertex (3, v3); 290 setVertex (3, v3);
311 if (isSelected() and document() != null) 306 if (isSelected() and document() != null)
312 deselect(); 307 deselect();
313 308
314 // If this object was associated to a file, remove it off it now 309 // If this object was associated to a file, remove it off it now
315 if (document() != null) 310 if (document() != null)
316 document().toStrongRef()->forgetObject (self()); 311 document()->forgetObject (self());
317 312
318 // Delete the GL lists 313 // Delete the GL lists
319 if (g_win != null) 314 if (g_win != null)
320 g_win->R()->forgetObject (self()); 315 g_win->R()->forgetObject (self());
321 316
335 delete this; 330 delete this;
336 } 331 }
337 332
338 // ============================================================================= 333 // =============================================================================
339 // 334 //
340 void LDObject::setDocument (const LDDocumentWeakPtr& a) 335 void LDObject::setDocument (LDDocument* a)
341 { 336 {
342 m_document = a; 337 m_document = a;
343 338
344 if (a == null) 339 if (a == null)
345 setSelected (false); 340 setSelected (false);
445 // ----------------------------------------------------------------------------- 440 // -----------------------------------------------------------------------------
446 long LDObject::lineNumber() const 441 long LDObject::lineNumber() const
447 { 442 {
448 assert (document() != null); 443 assert (document() != null);
449 444
450 for (int i = 0; i < document().toStrongRef()->getObjectCount(); ++i) 445 for (int i = 0; i < document()->getObjectCount(); ++i)
451 { 446 {
452 if (document().toStrongRef()->getObject (i) == this) 447 if (document()->getObject (i) == this)
453 return i; 448 return i;
454 } 449 }
455 450
456 return -1; 451 return -1;
457 } 452 }
546 541
547 // ============================================================================= 542 // =============================================================================
548 // 543 //
549 LDObjectPtr LDObject::topLevelParent() 544 LDObjectPtr LDObject::topLevelParent()
550 { 545 {
551 if (parent() == null) 546 LDObject* it;
552 return self(); 547
553 548 for (it = self(); it->parent(); it = it->parent())
554 LDObjectWeakPtr it (self()); 549 ;
555 550
556 while (it.toStrongRef()->parent() != null) 551 return it;
557 it = it.toStrongRef()->parent();
558
559 return it.toStrongRef();
560 } 552 }
561 553
562 // ============================================================================= 554 // =============================================================================
563 // 555 //
564 LDObjectPtr LDObject::next() const 556 LDObjectPtr LDObject::next() const
565 { 557 {
566 long idx = lineNumber(); 558 int idx = lineNumber();
567 assert (idx != -1); 559 assert (idx != -1);
568 560
569 if (idx == (long) document().toStrongRef()->getObjectCount() - 1) 561 if (idx == document()->getObjectCount() - 1)
570 return LDObjectPtr(); 562 return nullptr;
571 563
572 return document().toStrongRef()->getObject (idx + 1); 564 return document()->getObject (idx + 1);
573 } 565 }
574 566
575 // ============================================================================= 567 // =============================================================================
576 // 568 //
577 LDObjectPtr LDObject::previous() const 569 LDObjectPtr LDObject::previous() const
578 { 570 {
579 long idx = lineNumber(); 571 int idx = lineNumber();
580 assert (idx != -1); 572 assert (idx != -1);
581 573
582 if (idx == 0) 574 if (idx == 0)
583 return LDObjectPtr(); 575 return nullptr;
584 576
585 return document().toStrongRef()->getObject (idx - 1); 577 return document()->getObject (idx - 1);
586 } 578 }
587 579
588 // ============================================================================= 580 // =============================================================================
589 // 581 //
590 bool LDObject::previousIsInvertnext (LDBFCPtr& ptr) 582 bool LDObject::previousIsInvertnext (LDBFC*& ptr)
591 { 583 {
592 LDObjectPtr prev (previous()); 584 LDObject* prev = previous();
593 585
594 if (prev != null and prev->type() == OBJ_BFC and 586 if (prev and prev->type() == OBJ_BFC and static_cast<LDBFC*> (prev)->statement() == BFCStatement::InvertNext)
595 prev.staticCast<LDBFC>()->statement() == BFCStatement::InvertNext) 587 {
596 { 588 ptr = static_cast<LDBFC*> (prev);
597 ptr = prev.staticCast<LDBFC>();
598 return true; 589 return true;
599 } 590 }
600 591
601 return false; 592 return false;
602 } 593 }
605 // 596 //
606 void LDObject::move (Vertex vect) 597 void LDObject::move (Vertex vect)
607 { 598 {
608 if (hasMatrix()) 599 if (hasMatrix())
609 { 600 {
610 LDMatrixObjectPtr mo = self().toStrongRef().dynamicCast<LDMatrixObject>(); 601 LDMatrixObject* mo = static_cast<LDMatrixObject*> (this);
611 mo->setPosition (mo->position() + vect); 602 mo->setPosition (mo->position() + vect);
612 } 603 }
613 elif (type() == OBJ_Vertex) 604 else if (type() == OBJ_Vertex)
614 { 605 {
615 // ugh 606 // ugh
616 self().toStrongRef().staticCast<LDVertex>()->pos += vect; 607 static_cast<LDVertex*> (self)->pos += vect;
617 } 608 }
618 else 609 else
619 { 610 {
620 for (int i = 0; i < numVertices(); ++i) 611 for (int i = 0; i < numVertices(); ++i)
621 setVertex (i, vertex (i) + vect); 612 setVertex (i, vertex (i) + vect);
639 case OBJ_Error: return LDSpawn<LDError>(); 630 case OBJ_Error: return LDSpawn<LDError>();
640 case OBJ_Vertex: return LDSpawn<LDVertex>(); 631 case OBJ_Vertex: return LDSpawn<LDVertex>();
641 case OBJ_Overlay: return LDSpawn<LDOverlay>(); 632 case OBJ_Overlay: return LDSpawn<LDOverlay>();
642 case OBJ_NumTypes: assert (false); 633 case OBJ_NumTypes: assert (false);
643 } 634 }
644 return LDObjectPtr(); 635 return nullptr;
645 } 636 }
646 637
647 // ============================================================================= 638 // =============================================================================
648 // 639 //
649 void LDObject::invert() {} 640 void LDObject::invert() {}
667 658
668 // ============================================================================= 659 // =============================================================================
669 // 660 //
670 void LDQuad::invert() 661 void LDQuad::invert()
671 { 662 {
672 // Quad: 0 -> 1 -> 2 -> 3 663 // Quad: 0 -> 1 -> 2 -> 3
673 // rev: 0 -> 3 -> 2 -> 1 664 // reversed: 0 -> 3 -> 2 -> 1
674 // Thus, we swap 1 and 3. 665 // Thus, we swap 1 and 3.
675 Vertex tmp = vertex (1); 666 Vertex tmp = vertex (1);
676 setVertex (1, vertex (3)); 667 setVertex (1, vertex (3));
677 setVertex (3, tmp); 668 setVertex (3, tmp);
678 } 669 }
679 670
680 // ============================================================================= 671 // =============================================================================
681 // 672 //
682 void LDSubfile::invert() 673 void LDSubfile::invert()
683 { 674 {
684 if (document() == null) 675 if (document() == nullptr)
685 return; 676 return;
686 677
687 // Check whether subfile is flat 678 // Check whether subfile is flat
688 int axisSet = (1 << X) | (1 << Y) | (1 << Z); 679 int axisSet = (1 << X) | (1 << Y) | (1 << Z);
689 LDObjectList objs = fileInfo()->inlineContents (true, false); 680 LDObjectList objs = fileInfo()->inlineContents (true, false);
741 return; 732 return;
742 } 733 }
743 } 734 }
744 735
745 // Not inverted, thus prefix it with a new invertnext. 736 // Not inverted, thus prefix it with a new invertnext.
746 document().toStrongRef()->insertObj (idx, LDSpawn<LDBFC> (BFCStatement::InvertNext)); 737 document->insertObj (idx, new LDBFC (BFCStatement::InvertNext));
747 } 738 }
748 739
749 // ============================================================================= 740 // =============================================================================
750 // 741 //
751 void LDLine::invert() 742 void LDLine::invert()
758 749
759 // ============================================================================= 750 // =============================================================================
760 // 751 //
761 void LDCondLine::invert() 752 void LDCondLine::invert()
762 { 753 {
763 // I don't think that a conditional line's control points need to be 754 // I don't think that a conditional line's control points need to be swapped, do they?
764 // swapped, do they?
765 Vertex tmp = vertex (0); 755 Vertex tmp = vertex (0);
766 setVertex (0, vertex (1)); 756 setVertex (0, vertex (1));
767 setVertex (1, tmp); 757 setVertex (1, tmp);
768 } 758 }
769 759
770 void LDVertex::invert() {} 760 void LDVertex::invert() {}
771 761
772 // ============================================================================= 762 // =============================================================================
773 // 763 //
774 LDLinePtr LDCondLine::toEdgeLine() 764 LDLine* LDCondLine::toEdgeLine()
775 { 765 {
776 LDLinePtr replacement (LDSpawn<LDLine>()); 766 LDLine* replacement = new LDLine;
777 767
778 for (int i = 0; i < replacement->numVertices(); ++i) 768 for (int i = 0; i < replacement->numVertices(); ++i)
779 replacement->setVertex (i, vertex (i)); 769 replacement->setVertex (i, vertex (i));
780 770
781 replacement->setColor (color()); 771 replacement->setColor (color());
782
783 replace (replacement); 772 replace (replacement);
784 return replacement; 773 return replacement;
785 } 774 }
786 775
787 // ============================================================================= 776 // =============================================================================
791 auto it = g_allObjects.find (id); 780 auto it = g_allObjects.find (id);
792 781
793 if (it != g_allObjects.end()) 782 if (it != g_allObjects.end())
794 return *it; 783 return *it;
795 784
796 return LDObjectPtr(); 785 return nullptr;
797 } 786 }
798 787
799 // ============================================================================= 788 // =============================================================================
800 // 789 //
801 QString LDOverlay::asText() const 790 QString LDOverlay::asText() const
813 // makes history stuff work out of the box. 802 // makes history stuff work out of the box.
814 // 803 //
815 template<typename T> 804 template<typename T>
816 static void changeProperty (LDObjectPtr obj, T* ptr, const T& val) 805 static void changeProperty (LDObjectPtr obj, T* ptr, const T& val)
817 { 806 {
818 long idx; 807 int idx;
819 808
820 if (*ptr == val) 809 if (*ptr == val)
821 return; 810 return;
822 811
823 if (obj->document() != null and (idx = obj->lineNumber()) != -1) 812 if (obj->document() and (idx = obj->lineNumber()) != -1)
824 { 813 {
825 QString before = obj->asText(); 814 QString before = obj->asText();
826 *ptr = val; 815 *ptr = val;
827 QString after = obj->asText(); 816 QString after = obj->asText();
828 817
829 if (before != after) 818 if (before != after)
830 { 819 {
831 obj->document().toStrongRef()->addToHistory (new EditHistory (idx, before, after)); 820 obj->document()->addToHistory (new EditHistory (idx, before, after));
832 g_win->R()->compileObject (obj); 821 g_win->R()->compileObject (obj);
833 CurrentDocument()->redoVertices(); 822 CurrentDocument()->redoVertices();
834 } 823 }
835 } 824 }
836 else 825 else
826 {
837 *ptr = val; 827 *ptr = val;
828 }
838 } 829 }
839 830
840 // ============================================================================= 831 // =============================================================================
841 // 832 //
842 void LDObject::setColor (LDColor const& val) 833 void LDObject::setColor (LDColor const& val)
874 865
875 // ============================================================================= 866 // =============================================================================
876 // 867 //
877 void LDObject::select() 868 void LDObject::select()
878 { 869 {
879 assert (document() != null); 870 if (document() != null)
880 document().toStrongRef()->addToSelection (self()); 871 document()->addToSelection (self());
881
882 // If this object is inverted with INVERTNEXT, pick the INVERTNEXT as well.
883 /*
884 LDBFCPtr invertnext;
885
886 if (previousIsInvertnext (invertnext))
887 invertnext->select();
888 */
889 } 872 }
890 873
891 // ============================================================================= 874 // =============================================================================
892 // 875 //
893 void LDObject::deselect() 876 void LDObject::deselect()
894 { 877 {
895 assert (document() != null); 878 if (document() != null)
896 document().toStrongRef()->removeFromSelection (self()); 879 {
897 880 document()->removeFromSelection (self());
898 // If this object is inverted with INVERTNEXT, deselect the INVERTNEXT as well. 881
899 LDBFCPtr invertnext; 882 // If this object is inverted with INVERTNEXT, deselect the INVERTNEXT as well.
900 883 LDBFCPtr invertnext;
901 if (previousIsInvertnext (invertnext)) 884
902 invertnext->deselect(); 885 if (previousIsInvertnext (invertnext))
886 invertnext->deselect();
887 }
903 } 888 }
904 889
905 // ============================================================================= 890 // =============================================================================
906 // 891 //
907 QString PreferredLicenseText() 892 QString PreferredLicenseText()

mercurial