Begin proper memory management on taxonomy

This commit is contained in:
Thomas Krijnen
2020-11-04 13:46:25 +01:00
parent e39c7e7195
commit 059de764d6
2 changed files with 27 additions and 18 deletions
+22 -18
View File
@@ -75,12 +75,10 @@ namespace {
if (loop) { if (loop) {
loop->external = true; loop->external = true;
face_ = taxonomy::face(); face_.emplace();
face_->instance = loop->instance; face_->instance = loop->instance;
face_->matrix = loop->matrix; face_->matrix = loop->matrix;
// @todo make sure loop is not freed face_->children = { loop->clone() };
// this is accounted for below with as::upgraded_
face_->children = { loop };
} }
} }
@@ -107,22 +105,20 @@ namespace {
class as { class as {
private: private:
taxonomy::item* item_; taxonomy::item* item_;
mutable bool upgraded_;
public: public:
as(taxonomy::item* item) : item_(item), upgraded_(false) {} as(taxonomy::item* item) : item_(item) {}
operator T() const { operator T() const {
if (!item_) { if (!item_) {
throw taxonomy::topology_error("item was nullptr"); throw taxonomy::topology_error("item was nullptr");
} }
T* t = dynamic_cast<T*>(item_); T* t = dynamic_cast<T*>(item_);
if (t) { if (t) {
return *t; return T(*t);
} else { } else {
{ {
loop_to_face_upgrade<T> upgrade(item_); loop_to_face_upgrade<T> upgrade(item_);
if (upgrade) { if (upgrade) {
upgraded_ = true;
return upgrade; return upgrade;
} }
} }
@@ -130,10 +126,7 @@ namespace {
} }
} }
~as() { ~as() {
if (!upgraded_) { delete item_;
// @todo revisit this
delete item_;
}
} }
}; };
@@ -204,7 +197,7 @@ namespace {
auto filtered = new taxonomy::collection; auto filtered = new taxonomy::collection;
for (auto& child : collection->children) { for (auto& child : collection->children) {
if (apply_predicate_to_collection(child, fn)) { if (apply_predicate_to_collection(child, fn)) {
filtered->children.push_back(child); filtered->children.push_back(child->clone());
} }
} }
if (filtered->children.empty()) { if (filtered->children.empty()) {
@@ -213,6 +206,18 @@ namespace {
} }
return filtered; return filtered;
} }
// @nb traverses nested collections
template <typename Fn>
taxonomy::collection* filter_in_place(taxonomy::collection* collection, Fn fn) {
for (auto it = --collection->children.end(); it >= collection->children.begin(); --it) {
if (!apply_predicate_to_collection(*it, fn)) {
delete *it;
collection->children.erase(it);
}
}
return collection;
}
} }
taxonomy::item* mapping::map_impl(const IfcSchema::IfcRepresentation* inst) { taxonomy::item* mapping::map_impl(const IfcSchema::IfcRepresentation* inst) {
@@ -232,14 +237,10 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcRepresentation* inst) {
} }
*/ */
auto filtered = filter(items, [&use_body](taxonomy::item* i) { return filter_in_place(items, [&use_body](taxonomy::item* i) {
// @todo just filter loops for now. // @todo just filter loops for now.
return (i->kind() != taxonomy::LOOP) == use_body; return (i->kind() != taxonomy::LOOP) == use_body;
}); });
delete items;
return filtered;
} }
taxonomy::item* mapping::map_impl(const IfcSchema::IfcFaceBasedSurfaceModel* inst) { taxonomy::item* mapping::map_impl(const IfcSchema::IfcFaceBasedSurfaceModel* inst) {
@@ -277,11 +278,14 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcFace* inst) {
r->reverse(); r->reverse();
} }
if (bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class())) { if (bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class())) {
((taxonomy::loop*)r)->external = true;
/*
// Make a copy in case we need immutability later for e.g. caching // Make a copy in case we need immutability later for e.g. caching
auto s = r->clone(); auto s = r->clone();
((taxonomy::loop*)s)->external = true; ((taxonomy::loop*)s)->external = true;
delete r; delete r;
r = s; r = s;
*/
} }
face->children.push_back(r); face->children.push_back(r);
} }
+5
View File
@@ -344,6 +344,11 @@ struct edge : public trimmed_curve {
struct collection : public geom_item { struct collection : public geom_item {
std::vector<item*> children; std::vector<item*> children;
collection() {}
collection(const collection& other) {
std::transform(other.children.begin(), other.children.end(), std::back_inserter(children), std::mem_fun(&item::clone));
}
template <typename T> template <typename T>
std::vector<T*> children_as() const { std::vector<T*> children_as() const {
std::vector<T*> ts; std::vector<T*> ts;