From e57affde26b08e3a9ebec34816109a2998bc1565 Mon Sep 17 00:00:00 2001 From: Venelin Date: Mon, 13 Feb 2023 22:03:36 +0200 Subject: [PATCH] add updateRels --- common/basicTypes.h | 2 - compile.sh | 2 +- compile_debug.sh | 2 +- main.cpp | 4 +- person.cpp | 4 +- person.h => person.hpp | 0 todo.txt | 11 +-- tree.cpp | 161 +++++++++++++++++++++++++++-------------- tree.h => tree.hpp | 30 +++++--- help.cpp => utils.cpp | 2 +- help.h => utils.hpp | 0 11 files changed, 139 insertions(+), 79 deletions(-) rename person.h => person.hpp (100%) rename tree.h => tree.hpp (72%) rename help.cpp => utils.cpp (95%) rename help.h => utils.hpp (100%) diff --git a/common/basicTypes.h b/common/basicTypes.h index efbec6d..62f71c0 100644 --- a/common/basicTypes.h +++ b/common/basicTypes.h @@ -10,5 +10,3 @@ typedef int32_t I32; typedef uint32_t U32; typedef int64_t I64; typedef uint64_t U64; - - diff --git a/compile.sh b/compile.sh index 6a9f9f0..442f3b4 100755 --- a/compile.sh +++ b/compile.sh @@ -25,7 +25,7 @@ warnings=' # each global variable is only declared once per single object. -other='-fno-common -fno-fat-lto-objects' +other='-fno-common -fno-fat-lto-objects -march=native' g++ -o bin/release/famt $language $optimizations $warnings $other -DNDEBUG -s *.cpp -lncursesw #-static -lncursesw -ltinfo diff --git a/compile_debug.sh b/compile_debug.sh index ae2f66f..d94df72 100755 --- a/compile_debug.sh +++ b/compile_debug.sh @@ -9,4 +9,4 @@ warnings=' -Wmultiple-inheritance -Wvirtual-inheritance' #-fanalyzer -g++ -o bin/debug/famt -std=gnu++20 -g -O0 $warnings *.cpp -lncursesw +g++ -o bin/debug/famt -std=gnu++20 -g -O0 -march=native $warnings *.cpp -lncursesw diff --git a/main.cpp b/main.cpp index d9e3ab8..b59e1bf 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,7 @@ #include #include -#include "tree.h" -#include "help.h" +#include "tree.hpp" +#include "utils.hpp" using std::cin; using std::cout; diff --git a/person.cpp b/person.cpp index 1884061..74afb71 100644 --- a/person.cpp +++ b/person.cpp @@ -3,8 +3,8 @@ #include #include -#include"person.h" -#include "help.h" +#include"person.hpp" +#include "utils.hpp" using std::cout; diff --git a/person.h b/person.hpp similarity index 100% rename from person.h rename to person.hpp diff --git a/todo.txt b/todo.txt index afc248b..2225f87 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,6 @@ Help -addPerson add siblings (add relation improve) - -findRelative +ffindRelative findRelation - extend @@ -25,10 +23,13 @@ Compilation - coordinate types for large trees Backend +- file operatons check if file exists - move to SQLlite - create tree backup Refactoring -- check if vector combine && works correctly -- nobody = 0 +- gender enum +- person struct - comment style /* + +readelf -a /usr/lib/x86_64-linux-gnu/libncursesw.a | grep lto diff --git a/tree.cpp b/tree.cpp index cdaa0db..51b9be6 100644 --- a/tree.cpp +++ b/tree.cpp @@ -1,11 +1,10 @@ -#include"tree.h" +#include"tree.hpp" #include #include #include -#include"person.h" -#include"help.h" +#include"person.hpp" +#include"utils.hpp" -using std::cout; using std::ofstream; using std::ifstream; using std::vector; @@ -124,12 +123,12 @@ person_id Tree::findOldestAncestor(person_id id, bool isMale) const return id; } -person_id Tree::findCommonAncestor(const unsigned firstId, const unsigned secondId) const +person_id Tree::findCommonAncestor(const unsigned first, const unsigned second) const { vector visited(numPeople); //if a member is visited twice he's a common ancestor - commonAncestorRec(firstId, visited); - commonAncestorRec(secondId, visited); + commonAncestorRec(first, visited); + commonAncestorRec(second, visited); person_id oldest = Nobody; U16 oldestBday = SHRT_MAX; @@ -155,8 +154,11 @@ person_id Tree::findParent(person_id child, bool isParentMale) const return parent; } -std::vector Tree::findChildren(person_id person) const +vector Tree::findChildren(person_id person) const { + if(person == Nobody) + return {}; + vector children; for(const Relation& rel: relations[person]) { @@ -166,6 +168,17 @@ std::vector Tree::findChildren(person_id person) const return children; } +vector Tree::findChildren(person_id person, person_id exclude) const +{ + vector children = findChildren(person); + for(U32 i = 0; i < children.size(); ++i) + { + if(children[i] == exclude) + remove(children, i); + } + return children; +} + person_id Tree::findSpouse(person_id person) const { person_id spouse = Nobody; @@ -232,15 +245,16 @@ bool Tree::loadFromFile() void Tree::addPerson(const char* name, bool isMale, unsigned father, unsigned mother, EventTime birth, EventTime death) { - Person newPerson(name, birth, isMale, death); - people.push_back(newPerson); + people.emplace_back(name, birth, isMale, death); - vector newRels; - relations.push_back(newRels); + relations.emplace_back(); /* relations of the new person */ ++numPeople; - addRelation(father, Parent, numPeople - 1); - addRelation(mother, Parent, numPeople - 1); + person_id new_person_id = numPeople - 1; + addRelation(father, Parent, new_person_id); + addRelation(mother, Parent, new_person_id); + + updateRels(new_person_id); } bool Tree::addRelation(const char* firstName, const RelType type, const char* secondName) @@ -249,47 +263,56 @@ bool Tree::addRelation(const char* firstName, const RelType type, const char* se return addRelation(findId(firstName), type, findId(secondName)); } -bool Tree::addRelation(const unsigned firstId, const RelType type, const unsigned secondId, bool opposite)// +bool Tree::addRelation(const unsigned first, const RelType type, const unsigned second, bool update) { - if (firstId == Nobody || firstId >= numPeople || secondId == Nobody || secondId >= numPeople || type == None) + if (first == Nobody || first >= numPeople || second == Nobody || second >= numPeople || type == None) return false; - unsigned i = 0; - for (; i < relations[firstId].size(); ++i) //If they are already relatives + switch (type) { - if (relations[firstId][i].id == secondId) - { - relations[firstId][i].type = type; - break; - } - } - if (i >= relations[firstId].size()) - { - relations[firstId].push_back({secondId, type}); + case Parent: + addRelOneSide(first, Parent, second); + addRelOneSide(second, Child, first); + break; + case Child: + addRelOneSide(first, Child, second); + addRelOneSide(second, Parent, first); + break; + case Sibling: + case HalfSibling: + case Spouse: + case ExSpouse: + addRelOneSide(first, type, second); + addRelOneSide(second, type, first); + break; + default: assert(!"Unexpected case"); break; } - if (!opposite) + if(update) { - switch (type) - { - case Parent: - addRelation(secondId, Child, firstId, 1); - break; - case Child: - addRelation(secondId, Parent, firstId, 1); - break; - case Sibling: - case HalfSibling: - case Spouse: - case ExSpouse: - addRelation(secondId, type, firstId, 1); - break; - default: assert(!"Unexpected case"); break; - } + updateRels(first); + updateRels(second); } return true; } +void Tree::addRelOneSide(person_id first, RelType type, person_id second) +{ + unsigned i = 0; + for (; i < relations[first].size(); ++i) //Check if they are already relatives + { + if (relations[first][i].id == second) + { + relations[first][i].type = type; + break; + } + } + if (i >= relations[first].size()) + { + relations[first].push_back({second, type}); + } +} + void Tree::removeRelation(const char* firstName, const char* secondName) { removeRelation(findId(firstName), findId(secondName)); @@ -332,21 +355,21 @@ void Tree::removePerson(const person_id id) /* removePerson(findId(personName, year, month, day)); */ /* } */ -void Tree::removeRelation(const unsigned firstId, const unsigned secondId) +void Tree::removeRelation(const unsigned first, const unsigned second) { - for (unsigned i = 0; i < relations[firstId].size(); ++i) + for (unsigned i = 0; i < relations[first].size(); ++i) { - if (relations[firstId][i].id == secondId) + if (relations[first][i].id == second) { - remove(relations[firstId], i); + remove(relations[first], i); break; } } - for (unsigned i = 0; i < relations[secondId].size(); ++i) + for (unsigned i = 0; i < relations[second].size(); ++i) { - if (relations[secondId][i].id == firstId) + if (relations[second][i].id == first) { - remove(relations[secondId], i); + remove(relations[second], i); break; } } @@ -405,6 +428,38 @@ void Tree::display() while(c != 'W'); } +void Tree::updateRels(person_id id) +{ + person_id dad = findParent(id, true); + person_id mom = findParent(id, false); + + auto dad_children = findChildren(dad, id); + auto mom_children = findChildren(mom, id); + + for(U32 i = 0; i < dad_children.size(); ++i) + { + for(U32 j = 0; j < mom_children.size(); ++j) + { + /* full sibling found, add and continue */ + if (dad_children[i] == mom_children[j]) + { + addRelation(id, Sibling, dad_children[i], false); + remove(dad_children, i); + remove(mom_children, j); + --i; + break; + } + } + } + + for(U32 i = 0; i < dad_children.size(); ++i) + addRelation(id, HalfSibling, dad_children[i], false); + for(U32 i = 0; i < mom_children.size(); ++i) + addRelation(id, HalfSibling, mom_children[i], false); + +} + + void Tree::draw() const { erase(); //Clear the screen @@ -545,7 +600,7 @@ static U8 linkToChild(I16 startY, I16 startX, I16 endX, bool moreSiblings) /* { */ /* people[id].draw(drawY, drawX, true, false, true); */ -/* std::vector children; */ +/* vector children; */ /* for(U32 i=0; i children; + vector children; for(const auto& rel: rels) { if (rel.type == RelType::Parent) diff --git a/tree.h b/tree.hpp similarity index 72% rename from tree.h rename to tree.hpp index f752dc9..09b0074 100644 --- a/tree.h +++ b/tree.hpp @@ -2,7 +2,7 @@ #include #include -#include "person.h" +#include "person.hpp" using person_id = U32; enum RelType : U8 @@ -45,49 +45,55 @@ public: void rename(const char* newName); person_id findId(const char* name, bool=true) const; - person_id findOldestAncestor(person_id id, bool sex = 0) const;// + person_id findOldestAncestor(person_id, bool sex = 0) const;// //oldest common ancestor ID, a person is considerd an ancestor of himself - person_id findCommonAncestor(person_id firstId, person_id secondId) const; + person_id findCommonAncestor(person_id first, person_id second) const; RelType findRelation(person_id first, person_id second) const; person_id findParent(person_id child, bool isParentMale) const; person_id findSpouse(person_id person) const; std::vector findChildren(person_id person) const; + std::vector findChildren(person_id person, person_id exclude) const; void saveToFile()const;// bool loadFromFile(); void addPerson(const char* name, bool isMale, person_id father=Nobody, person_id mother=Nobody, EventTime birth={}, EventTime death={}); bool addRelation(const char* firstName, RelType, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success - bool addRelation(person_id firstId, RelType, person_id secondId, bool opposite=0); //0 - failure 1 - success + bool addRelation(person_id first, RelType, person_id second, bool update=true); //0 - failure 1 - success void removePerson(person_id id); //Removes a member and the last one takes his ID /* void removePerson(const char*, short year = 0, const unsigned char month = 0, const unsigned char day = 0); */ - void removeRelation(person_id firstId, person_id secondId); + void removeRelation(person_id first, person_id second); void removeRelation(const char* firstName, const char* secondName); void display(); void print()const; /* void printRel(person_id id)const; //Prints out close relatives */ - void printMember(person_id id)const; - void printOldestAncestors(person_id id)const;// + void printMember(person_id)const; + void printOldestAncestors(person_id)const;// private: - void commonAncestorRec(person_id id, std::vector &visited)const; + void commonAncestorRec(person_id, std::vector &visited)const; + + void addRelOneSide(person_id first, RelType, person_id second); + /* update a person's relations after adding a relation + (example adds siblings after parents are added) */ + void updateRels(person_id); void draw() const; /* draw a line of people starting from person with id return the farthest X that will be drawn */ - I16 drawLine(person_id id, I16 drawY, I16 drawX) const; - I16 drawLineWithWives(person_id id, I16 drawY, I16 drawX) const; + I16 drawLine(person_id, I16 drawY, I16 drawX) const; + I16 drawLineWithWives(person_id, I16 drawY, I16 drawX) const; void selectLeft(); void selectDown(); void selectUp(); void selectRight(); - void selectLeftSibSpouse(person_id person); - void selectRightSib(person_id person); + void selectLeftSibSpouse(person_id); + void selectRightSib(person_id); std::string treeName; unsigned numPeople = 0; diff --git a/help.cpp b/utils.cpp similarity index 95% rename from help.cpp rename to utils.cpp index 72234af..15f2540 100644 --- a/help.cpp +++ b/utils.cpp @@ -1,4 +1,4 @@ -#include "help.h" +#include "utils.hpp" bool willBeVisible(I16 drawY, I16 drawX, U16 height, U16 width) { diff --git a/help.h b/utils.hpp similarity index 100% rename from help.h rename to utils.hpp