add updateRels

This commit is contained in:
vrd
2023-02-13 22:18:53 +02:00
parent 818a20b20e
commit e57affde26
11 changed files with 139 additions and 79 deletions
-2
View File
@@ -10,5 +10,3 @@ typedef int32_t I32;
typedef uint32_t U32; typedef uint32_t U32;
typedef int64_t I64; typedef int64_t I64;
typedef uint64_t U64; typedef uint64_t U64;
+1 -1
View File
@@ -25,7 +25,7 @@ warnings='
# each global variable is only declared once per single object. # 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 g++ -o bin/release/famt $language $optimizations $warnings $other -DNDEBUG -s *.cpp -lncursesw
#-static -lncursesw -ltinfo #-static -lncursesw -ltinfo
+1 -1
View File
@@ -9,4 +9,4 @@ warnings='
-Wmultiple-inheritance -Wmultiple-inheritance
-Wvirtual-inheritance' #-fanalyzer -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
+2 -2
View File
@@ -1,7 +1,7 @@
#include <ncursesw/ncurses.h> #include <ncursesw/ncurses.h>
#include <iostream> #include <iostream>
#include "tree.h" #include "tree.hpp"
#include "help.h" #include "utils.hpp"
using std::cin; using std::cin;
using std::cout; using std::cout;
+2 -2
View File
@@ -3,8 +3,8 @@
#include<ctype.h> #include<ctype.h>
#include <ncursesw/ncurses.h> #include <ncursesw/ncurses.h>
#include"person.h" #include"person.hpp"
#include "help.h" #include "utils.hpp"
using std::cout; using std::cout;
View File
+6 -5
View File
@@ -1,8 +1,6 @@
Help Help
addPerson add siblings (add relation improve) ffindRelative
findRelative
findRelation - extend findRelation - extend
@@ -25,10 +23,13 @@ Compilation
- coordinate types for large trees - coordinate types for large trees
Backend Backend
- file operatons check if file exists
- move to SQLlite - move to SQLlite
- create tree backup - create tree backup
Refactoring Refactoring
- check if vector combine && works correctly - gender enum
- nobody = 0 - person struct
- comment style /* - comment style /*
readelf -a /usr/lib/x86_64-linux-gnu/libncursesw.a | grep lto
+108 -53
View File
@@ -1,11 +1,10 @@
#include"tree.h" #include"tree.hpp"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <assert.h> #include <assert.h>
#include"person.h" #include"person.hpp"
#include"help.h" #include"utils.hpp"
using std::cout;
using std::ofstream; using std::ofstream;
using std::ifstream; using std::ifstream;
using std::vector; using std::vector;
@@ -124,12 +123,12 @@ person_id Tree::findOldestAncestor(person_id id, bool isMale) const
return id; 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<U8> visited(numPeople); //if a member is visited twice he's a common ancestor vector<U8> visited(numPeople); //if a member is visited twice he's a common ancestor
commonAncestorRec(firstId, visited); commonAncestorRec(first, visited);
commonAncestorRec(secondId, visited); commonAncestorRec(second, visited);
person_id oldest = Nobody; person_id oldest = Nobody;
U16 oldestBday = SHRT_MAX; U16 oldestBday = SHRT_MAX;
@@ -155,8 +154,11 @@ person_id Tree::findParent(person_id child, bool isParentMale) const
return parent; return parent;
} }
std::vector<person_id> Tree::findChildren(person_id person) const vector<person_id> Tree::findChildren(person_id person) const
{ {
if(person == Nobody)
return {};
vector<person_id> children; vector<person_id> children;
for(const Relation& rel: relations[person]) for(const Relation& rel: relations[person])
{ {
@@ -166,6 +168,17 @@ std::vector<person_id> Tree::findChildren(person_id person) const
return children; return children;
} }
vector<person_id> Tree::findChildren(person_id person, person_id exclude) const
{
vector<person_id> 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 Tree::findSpouse(person_id person) const
{ {
person_id spouse = Nobody; 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) void Tree::addPerson(const char* name, bool isMale, unsigned father, unsigned mother, EventTime birth, EventTime death)
{ {
Person newPerson(name, birth, isMale, death); people.emplace_back(name, birth, isMale, death);
people.push_back(newPerson);
vector<Relation> newRels; relations.emplace_back(); /* relations of the new person */
relations.push_back(newRels);
++numPeople; ++numPeople;
addRelation(father, Parent, numPeople - 1); person_id new_person_id = numPeople - 1;
addRelation(mother, Parent, 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) 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)); 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; return false;
unsigned i = 0; switch (type)
for (; i < relations[firstId].size(); ++i) //If they are already relatives
{ {
if (relations[firstId][i].id == secondId) case Parent:
{ addRelOneSide(first, Parent, second);
relations[firstId][i].type = type; addRelOneSide(second, Child, first);
break; break;
} case Child:
} addRelOneSide(first, Child, second);
if (i >= relations[firstId].size()) addRelOneSide(second, Parent, first);
{ break;
relations[firstId].push_back({secondId, type}); 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) updateRels(first);
{ updateRels(second);
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;
}
} }
return true; 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) void Tree::removeRelation(const char* firstName, const char* secondName)
{ {
removeRelation(findId(firstName), findId(secondName)); removeRelation(findId(firstName), findId(secondName));
@@ -332,21 +355,21 @@ void Tree::removePerson(const person_id id)
/* removePerson(findId(personName, year, month, day)); */ /* 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; 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; break;
} }
} }
@@ -405,6 +428,38 @@ void Tree::display()
while(c != 'W'); 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 void Tree::draw() const
{ {
erase(); //Clear the screen 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); */ /* people[id].draw(drawY, drawX, true, false, true); */
/* std::vector<person_id> children; */ /* vector<person_id> children; */
/* for(U32 i=0; i<relations[id].size(); ++i) */ /* for(U32 i=0; i<relations[id].size(); ++i) */
/* { */ /* { */
/* if (relations[id][i].type == RelType::Parent) */ /* if (relations[id][i].type == RelType::Parent) */
@@ -578,7 +633,7 @@ I16 Tree::drawLineWithWives(const person_id id, I16 drawY, const I16 drawX) cons
const auto& rels = relations[id]; const auto& rels = relations[id];
person_id spouse = Nobody; person_id spouse = Nobody;
std::vector<person_id> children; vector<person_id> children;
for(const auto& rel: rels) for(const auto& rel: rels)
{ {
if (rel.type == RelType::Parent) if (rel.type == RelType::Parent)
+18 -12
View File
@@ -2,7 +2,7 @@
#include <climits> #include <climits>
#include <vector> #include <vector>
#include "person.h" #include "person.hpp"
using person_id = U32; using person_id = U32;
enum RelType : U8 enum RelType : U8
@@ -45,49 +45,55 @@ public:
void rename(const char* newName); void rename(const char* newName);
person_id findId(const char* name, bool=true) const; 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 //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; RelType findRelation(person_id first, person_id second) const;
person_id findParent(person_id child, bool isParentMale) const; person_id findParent(person_id child, bool isParentMale) const;
person_id findSpouse(person_id person) const; person_id findSpouse(person_id person) const;
std::vector<person_id> findChildren(person_id person) const; std::vector<person_id> findChildren(person_id person) const;
std::vector<person_id> findChildren(person_id person, person_id exclude) const;
void saveToFile()const;// void saveToFile()const;//
bool loadFromFile(); bool loadFromFile();
void addPerson(const char* name, bool isMale, person_id father=Nobody, person_id mother=Nobody, EventTime birth={}, EventTime death={}); 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(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(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 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 removeRelation(const char* firstName, const char* secondName);
void display(); void display();
void print()const; void print()const;
/* void printRel(person_id id)const; //Prints out close relatives */ /* void printRel(person_id id)const; //Prints out close relatives */
void printMember(person_id id)const; void printMember(person_id)const;
void printOldestAncestors(person_id id)const;// void printOldestAncestors(person_id)const;//
private: private:
void commonAncestorRec(person_id id, std::vector<U8> &visited)const; void commonAncestorRec(person_id, std::vector<U8> &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; void draw() const;
/* draw a line of people starting from person with id /* draw a line of people starting from person with id
return the farthest X that will be drawn */ return the farthest X that will be drawn */
I16 drawLine(person_id id, I16 drawY, I16 drawX) const; I16 drawLine(person_id, I16 drawY, I16 drawX) const;
I16 drawLineWithWives(person_id id, I16 drawY, I16 drawX) const; I16 drawLineWithWives(person_id, I16 drawY, I16 drawX) const;
void selectLeft(); void selectLeft();
void selectDown(); void selectDown();
void selectUp(); void selectUp();
void selectRight(); void selectRight();
void selectLeftSibSpouse(person_id person); void selectLeftSibSpouse(person_id);
void selectRightSib(person_id person); void selectRightSib(person_id);
std::string treeName; std::string treeName;
unsigned numPeople = 0; unsigned numPeople = 0;
+1 -1
View File
@@ -1,4 +1,4 @@
#include "help.h" #include "utils.hpp"
bool willBeVisible(I16 drawY, I16 drawX, U16 height, U16 width) bool willBeVisible(I16 drawY, I16 drawX, U16 height, U16 width)
{ {
View File