285efd69d909767ff742c376de960c31cdc375b9
1 /*
2 * Inkscape::GC::Anchored - base class for anchored GC-managed objects
3 *
4 * Authors:
5 * MenTaLguY <mental@rydia.net>
6 *
7 * Copyright (C) 2004 MenTaLguY
8 *
9 * Released under GNU GPL, read the file 'COPYING' for more information
10 */
12 #include <typeinfo>
13 #include "gc-anchored.h"
14 #include "debug/event-tracker.h"
15 #include "debug/event.h"
16 #include "util/share.h"
17 #include "util/format.h"
19 namespace Inkscape {
21 namespace GC {
23 class AnchorEvent : public Debug::Event {
24 public:
25 enum Type { ANCHOR, RELEASE };
27 AnchorEvent(GC::Anchored const *object, Type type)
28 : _base(Util::format("%p", Core::base(const_cast<Anchored *>(object)))),
29 _object(Util::format("%p", object)),
30 _class_name(Util::share_static_string(typeid(*object).name())),
31 _refcount(Util::format("%d", ( type == ANCHOR ? object->_anchored_refcount() + 1 : object->_anchored_refcount() - 1 ))),
32 _type(type)
33 {}
35 static Category category() { return REFCOUNT; }
37 Util::ptr_shared<char> name() const {
38 if ( _type == ANCHOR ) {
39 return Util::share_static_string("gc-anchor");
40 } else {
41 return Util::share_static_string("gc-release");
42 }
43 }
44 unsigned propertyCount() const { return 4; }
45 PropertyPair property(unsigned index) const {
46 switch (index) {
47 case 0:
48 return PropertyPair("base", _base);
49 case 1:
50 return PropertyPair("pointer", _object);
51 case 2:
52 return PropertyPair("class", _class_name);
53 case 3:
54 return PropertyPair("new-refcount", _refcount);
55 default:
56 return PropertyPair();
57 }
58 }
60 private:
61 Util::ptr_shared<char> _base;
62 Util::ptr_shared<char> _object;
63 Util::ptr_shared<char> _class_name;
64 Util::ptr_shared<char> _refcount;
65 Type _type;
66 };
68 Anchored::Anchor *Anchored::_new_anchor() const {
69 return new Anchor(this);
70 }
72 void Anchored::_free_anchor(Anchored::Anchor *anchor) const {
73 delete anchor;
74 }
76 void Anchored::anchor() const {
77 Debug::EventTracker<AnchorEvent> tracker(this, AnchorEvent::ANCHOR);
78 if (!_anchor) {
79 _anchor = _new_anchor();
80 }
81 _anchor->refcount++;
82 }
84 void Anchored::release() const {
85 Debug::EventTracker<AnchorEvent> tracker(this, AnchorEvent::RELEASE);
86 if (!--_anchor->refcount) {
87 _free_anchor(_anchor);
88 _anchor = NULL;
89 }
90 }
92 }
94 }
96 /*
97 Local Variables:
98 mode:c++
99 c-file-style:"stroustrup"
100 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
101 indent-tabs-mode:nil
102 fill-column:99
103 End:
104 */
105 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :