blob: 8aaa68e705b837006b22231420c72a006c3bdd17 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
/*
* Multiindex container for selection
*
* Authors:
* Adrian Boguszewski
*
* Copyright (C) 2016 Adrian Boguszewski
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include <sigc++/sigc++.h>
#include "object-set.h"
bool ObjectSet::add(SPObject* object) {
// any ancestor is in the set - do nothing
if (_anyAncestorIsInSet(object)) {
return false;
}
// very nice function, but needs refinement
// check if there is mutual ancestor for some elements, which can replace all of them in the set
// object = _getMutualAncestor(object);
// remove all descendants from the set
_removeDescendantsFromSet(object);
_add(object);
return true;
}
bool ObjectSet::remove(SPObject* object) {
// object is the top of subtree
if (contains(object)) {
_remove(object);
return true;
}
// any ancestor of object is in the set
if (_anyAncestorIsInSet(object)) {
_removeAncestorsFromSet(object);
return true;
}
// no object nor any parent in the set
return false;
}
bool ObjectSet::contains(SPObject* object) {
return container.get<hashed>().find(object) != container.get<hashed>().end();
}
void ObjectSet::clear() {
for (auto object: container) {
_remove(object);
}
}
int ObjectSet::size() {
return container.size();
}
bool ObjectSet::_anyAncestorIsInSet(SPObject *object) {
SPObject* o = object;
while (o != nullptr) {
if (contains(o)) {
return true;
}
o = o->parent;
}
return false;
}
void ObjectSet::_removeDescendantsFromSet(SPObject *object) {
for (auto& child: object->childList(false)) {
if (contains(child)) {
_remove(child);
// there is certainly no children of this child in the set
continue;
}
_removeDescendantsFromSet(child);
}
}
void ObjectSet::_remove(SPObject *object) {
releaseConnections[object].disconnect();
releaseConnections.erase(object);
container.get<hashed>().erase(object);
}
void ObjectSet::_add(SPObject *object) {
releaseConnections[object] = object->connectRelease(sigc::hide_return(sigc::mem_fun(*this, &ObjectSet::remove)));
container.push_back(object);
}
SPObject *ObjectSet::_getMutualAncestor(SPObject *object) {
SPObject *o = object;
bool flag = true;
while (o->parent != nullptr) {
for (auto &child: o->parent->childList(false)) {
if(child != o && !contains(child)) {
flag = false;
break;
}
}
if (!flag) {
break;
}
o = o->parent;
}
return o;
}
void ObjectSet::_removeAncestorsFromSet(SPObject *object) {
SPObject* o = object;
while (o->parent != nullptr) {
for (auto &child: o->parent->childList(false)) {
if (child != o) {
_add(child);
}
}
if (contains(o->parent)) {
_remove(o->parent);
break;
}
o = o->parent;
}
}
ObjectSet::~ObjectSet() {
clear();
}
multi_index_container::iterator ObjectSet::begin() {
return container.begin();
}
multi_index_container::iterator ObjectSet::end() {
return container.end();
}
|