X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcondition.cpp;h=5978250243f6e51b6fb1ebadeadbbd401f5003bf;hb=refs%2Fheads%2Fmaster;hp=1ff316c361f76f51d6f0c13db000cd21a4b621f1;hpb=746329e61ac9f26962af740b0b11dee716803521;p=poefilter.git diff --git a/source/condition.cpp b/source/condition.cpp index 1ff316c..5978250 100644 --- a/source/condition.cpp +++ b/source/condition.cpp @@ -16,6 +16,18 @@ void CompoundCondition::clone_to(CompoundCondition &other) const other.add((*i)->clone()); } +bool CompoundCondition::sub_equals(const CompoundCondition &other) const +{ + if(other.count()!=conditions.size()) + return false; + + for(unsigned i=0; iequals(other.get(i))) + return false; + + return true; +} + void CompoundCondition::add(Condition *cond) { if(!cond) @@ -100,12 +112,12 @@ Condition *CompoundCondition::dispatch_flatten(Condition *cond1, Condition *cond throw logic_error("CompoundCondition::dispatch_flatten"); } -Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, bool del) const +Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, const CompoundCondition &parent, bool del) { vector parts(2); parts[0] = cond1; parts[1] = cond2; - Condition *result = cond1->merge(parts, *this); + Condition *result = cond1->merge(parts, parent); if(del) { @@ -122,13 +134,13 @@ Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, bool return result; } -Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del) const +Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del) { bool merged = false; for(vector::iterator i=target->conditions.begin(); i!=target->conditions.end(); ++i) if((*i)->can_merge(*cond, *target)) { - Condition *m = merge_two(cond, *i, false); + Condition *m = merge_two(cond, *i, *target, false); delete *i; if(del) delete cond; @@ -149,7 +161,7 @@ Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition * return target; } -Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target) const +Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target) { for(vector::iterator i=cond->conditions.begin(); i!=cond->conditions.end(); ++i) add_merged_to(*i, target, false); @@ -171,10 +183,16 @@ AndCondition *AndCondition::clone() const return result; } +bool AndCondition::equals(const Condition &other) const +{ + const AndCondition *other_and = dynamic_cast(&other); + return (other_and ? sub_equals(*other_and) : false); +} + Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const { if(cond1->can_merge(*cond2, *this)) - return merge_two(cond1, cond2, true); + return merge_two(cond1, cond2, *this, true); AndCondition *result = new AndCondition; result->add(cond1); @@ -198,7 +216,7 @@ Condition *AndCondition::flatten(OrCondition *cond1, Condition *cond2) const unsigned count = cond1->count(); for(unsigned i=0; iget(i).clone(), (i+1clone() : cond2))) - result->add(sub); + add_merged_to(sub, result, true); delete cond1; if(result->is_viable()) @@ -221,7 +239,7 @@ Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const for(unsigned i=0; iget(i).clone(), cond2->get(j).clone())) - result->add(sub); + add_merged_to(sub, result, true); delete cond1; delete cond2; @@ -233,6 +251,82 @@ Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const return 0; } +bool AndCondition::can_merge(const Condition &other, const CompoundCondition &parent) const +{ + const AndCondition *other_and = dynamic_cast(&other); + if(!other_and || !dynamic_cast(&parent)) + return false; + + return merge(*this, *other_and, parent, 0); +} + +AndCondition *AndCondition::merge(const vector &conds, const CompoundCondition &parent) const +{ + if(conds.size()!=2) + return 0; + + const AndCondition *and1 = dynamic_cast(conds[0]); + const AndCondition *and2 = dynamic_cast(conds[1]); + if(!and1 || !and2 || !dynamic_cast(&parent)) + return 0; + + AndCondition *result = 0; + merge(*and1, *and2, parent, &result); + return result; +} + +bool AndCondition::merge(const AndCondition &cond1, const AndCondition &cond2, const CompoundCondition &parent, AndCondition **result) +{ + if(cond1.count()!=cond2.count()) + return false; + + int merge1 = -1; + vector used(cond1.count(), false); + for(unsigned i=0; i=0) + used[match] = true; + else if(merge1<0) + merge1 = i; + else + return false; + } + + if(merge1>=0) + { + vector merge_conds(2, 0); + merge_conds[0] = &cond1.get(merge1); + for(unsigned i=0; (!merge_conds[1] && ican_merge(*merge_conds[1], parent)) + return false; + + if(result) + { + *result = new AndCondition; + (*result)->add(merge_conds[0]->merge(merge_conds, parent)); + } + } + else if(result) + *result = new AndCondition; + + if(result) + { + for(unsigned i=0; iadd(cond2.get(i).clone()); + } + + return true; +} + bool AndCondition::is_viable() const { for(vector::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) @@ -255,10 +349,16 @@ OrCondition *OrCondition::clone() const return result; } +bool OrCondition::equals(const Condition &other) const +{ + const OrCondition *other_or = dynamic_cast(&other); + return (other_or ? sub_equals(*other_or) : false); +} + Condition *OrCondition::flatten(Condition *cond1, Condition *cond2) const { if(cond1->can_merge(*cond2, *this)) - return merge_two(cond1, cond2, true); + return merge_two(cond1, cond2, *this, true); OrCondition *result = new OrCondition; result->add(cond1); @@ -321,6 +421,23 @@ LinkedColorsCondition *LinkedColorsCondition::clone() const return new LinkedColorsCondition(colors); } +bool LinkedColorsCondition::equals(const Condition &other) const +{ + const LinkedColorsCondition *other_linked = dynamic_cast(&other); + if(!other_linked) + return false; + + for(unsigned i=0; i<7; ++i) + { + if(colors.colors[i]!=other_linked->colors.colors[i]) + return false; + if(!colors.colors[i]) + break; + } + + return true; +} + void LinkedColorsCondition::add_lines(list &st) const { FilterStatement::add_line(st, format("SocketGroup %s", colors.colors));