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
+108 -53
View File
@@ -1,11 +1,10 @@
#include"tree.h"
#include"tree.hpp"
#include <iostream>
#include <fstream>
#include <assert.h>
#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<U8> 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<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;
for(const Relation& rel: relations[person])
{
@@ -166,6 +168,17 @@ std::vector<person_id> Tree::findChildren(person_id person) const
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 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<Relation> 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<person_id> children; */
/* vector<person_id> children; */
/* for(U32 i=0; i<relations[id].size(); ++i) */
/* { */
/* 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];
person_id spouse = Nobody;
std::vector<person_id> children;
vector<person_id> children;
for(const auto& rel: rels)
{
if (rel.type == RelType::Parent)