From d82f06ff5e5b5cef51709d4618779772931e5e90 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20D=C5=82ugo=C5=82=C4=99cki?= Date: Thu, 6 Feb 2014 14:43:04 +0100 Subject: [PATCH] Added reading date from the GEDCOM file and storing it in individual. Fixed documentation. --- Makefile.am | 3 +- doc/model.dia | Bin 3577 -> 3614 bytes src/gedcom/familia_gedcom.c | 138 +++++++++++++++++++++++++++++++----- src/gedcom/familia_gedcom.h | 32 +++++++++ src/math/camera.c | 13 +++- src/math/positions.c | 63 +++++++++++++++- src/storage/individual.c | 36 ++++++++++ src/storage/individual.h | 74 +++++++++++++------ src/storage/positions.c | 4 +- src/storage/storage.h | 28 ++++---- 10 files changed, 329 insertions(+), 62 deletions(-) diff --git a/Makefile.am b/Makefile.am index 62441d7..d503be4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,7 @@ bin_familia_SOURCES = \ src/storage/positions.c \ src/math/positions.c \ src/math/camera.c \ + src/math/yearline.c \ src/graphics/individual.c \ src/graphics/family.c \ src/gedcom/familia_gedcom.c \ @@ -63,7 +64,7 @@ bin_familia_LDADD = \ $(GLU_LIBS) \ @GEDCOM_LIBS@ \ -L/usr/lib \ - -lzip + -lzip -lm bin_familia_LDFLAGS = $(LTLIBINTL) diff --git a/doc/model.dia b/doc/model.dia index f02a73883f9c70e9282efea6bc4c045783ac2cf2..a278c156b1efb24fa3acc7ef736a3dd21b0115c2 100644 GIT binary patch literal 3614 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, FS_FAMILY); return (Gedcom_ctxt)family; } -/* -void familia_gedcom_family_end (Gedcom_rec rec, Gedcom_ctxt self) + +void familia_gedcom_family_end (Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value) { - familia_storage_add_family(familia_storage_get_current(), self); +/* familia_storage_add_family(familia_storage_get_current(), self);*/ } -*/ + Gedcom_ctxt familia_gedcom_individual_start (Gedcom_rec rec, int level, Gedcom_val xref, @@ -100,16 +107,19 @@ Gedcom_ctxt familia_gedcom_individual_start (Gedcom_rec rec, struct familia_individual * individual = NULL; struct xref_value *xr = GEDCOM_XREF_PTR(xref); + assert(rec == REC_INDI); + assert(parsed_tag == TAG_INDI); + individual = familia_memory_stack_find(xr->string, FS_INDIVIDUAL); return (Gedcom_ctxt)individual; } -/* -void familia_gedcom_individual_end (Gedcom_rec rec, Gedcom_ctxt self) + +void familia_gedcom_individual_end (Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value) { - familia_storage_add_individual(familia_storage_get_current(), self); +/* familia_storage_add_individual(familia_storage_get_current(), self);*/ } -*/ + Gedcom_ctxt familia_gedcom_individual_set_first_name(Gedcom_elt elt, Gedcom_ctxt ctxt, int level, @@ -118,6 +128,9 @@ Gedcom_ctxt familia_gedcom_individual_set_first_name(Gedcom_elt elt, int parsed_tag, Gedcom_val parsed_value) { + assert(elt == ELT_SUB_PERS_NAME); + assert(parsed_tag == TAG_NAME); + familia_individual_set_first_name(ctxt, GEDCOM_STRING(parsed_value)); return ctxt; } @@ -137,6 +150,8 @@ Gedcom_ctxt familia_gedcom_individual_last_name_start(Gedcom_elt elt, int parsed_tag, Gedcom_val parsed_value) { + assert(elt == ELT_SUB_PERS_NAME_SURN); + if (GEDCOM_IS_STRING(parsed_value)) { familia_individual_set_last_name(ctxt, GEDCOM_STRING(parsed_value)); } @@ -160,7 +175,12 @@ Gedcom_ctxt familia_gedcom_individual_add_family(Gedcom_elt elt, Gedcom_val parsed_value) { void * family = NULL; - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_SUB_FAMS); + assert(parsed_tag == TAG_FAMS); + + xr = GEDCOM_XREF_PTR(parsed_value); family = familia_memory_stack_find(xr->string, FS_FAMILY); familia_individual_add_family(ctxt, family); @@ -181,7 +201,12 @@ Gedcom_ctxt familia_gedcom_individual_set_parents(Gedcom_elt elt, { void * child = NULL; /* XREF_PTR(FAM) */ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_FAM_CHIL); + assert(parsed_tag == TAG_CHIL); + + xr = GEDCOM_XREF_PTR(parsed_value); child = familia_memory_stack_find(xr->string, FS_INDIVIDUAL); familia_individual_set_parents(child, ctxt); @@ -202,7 +227,12 @@ Gedcom_ctxt familia_gedcom_family_add_child(Gedcom_elt elt, { void * family = NULL; /* XREF_PTR(FAM) */ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_SUB_FAMC); + assert(parsed_tag == TAG_FAMC); + + xr = GEDCOM_XREF_PTR(parsed_value); family = familia_memory_stack_find(xr->string, FS_FAMILY); familia_family_add_child(family, ctxt); @@ -224,7 +254,12 @@ Gedcom_ctxt familia_gedcom_family_set_parent1(Gedcom_elt elt, { void * parent = NULL; /* XREF_PTR(INDI) */ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_FAM_HUSB); + assert(parsed_tag == TAG_HUSB); + + xr = GEDCOM_XREF_PTR(parsed_value); parent = familia_memory_stack_find(xr->string, FS_FAMILY); /* ctxt: REC_FAM */ @@ -247,7 +282,12 @@ Gedcom_ctxt familia_gedcom_family_set_parent2(Gedcom_elt elt, { void * parent = NULL; /* XREF_PTR(INDI) */ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); + struct xref_value *xr = NULL; + + assert(elt == ELT_FAM_WIFE); + assert(parsed_tag == TAG_WIFE); + + xr = GEDCOM_XREF_PTR(parsed_value); parent = familia_memory_stack_find(xr->string, FS_FAMILY); /* ctxt: REC_FAM */ @@ -256,13 +296,70 @@ Gedcom_ctxt familia_gedcom_family_set_parent2(Gedcom_elt elt, return ctxt; } -/* -void familia_gedcom_individual_family_end(Gedcom_elt elt, +/** + * Sets date for the current event. Currently supports only individual birth. + * TODO: Implement all events. + */ +Gedcom_ctxt familia_gedcom_event_set_date(Gedcom_elt elt, + Gedcom_ctxt ctxt, + int level, + char* tag, + char* raw_value, + int parsed_tag, + Gedcom_val parsed_value) +{ + struct fged_timestampable_ctxt * tctxt = ctxt; + + switch(tctxt->type) { + case BIRTH: { + struct date_value dv; + struct familia_individual * ind = NULL; + + assert(GEDCOM_IS_DATE(parsed_value)); + + ind = ((struct fged_ctxt *)ctxt)->object; + dv = GEDCOM_DATE(parsed_value); + + familia_individual_set_birth_date(ind, dv); + break; + } + }; + + return ctxt; +} +Gedcom_ctxt familia_gedcom_timestampable_ctxt_wrap(Gedcom_elt elt, + Gedcom_ctxt ctxt, + int level, + char* tag, + char* raw_value, + int parsed_tag, + Gedcom_val parsed_value) +{ + struct fged_timestampable_ctxt * tctxt = NULL; + tctxt = (struct fged_timestampable_ctxt *)malloc(sizeof(struct fged_timestampable_ctxt)); + tctxt->ctxt = ctxt; + tctxt->type = UNSET; + + switch(elt) { + case ELT_SUB_INDIV_BIRT: + tctxt->type = BIRTH; + break; + } + return tctxt; +} + +void familia_gedcom_timestampable_ctxt_unwrap(Gedcom_elt elt, Gedcom_ctxt ctxt, Gedcom_ctxt self, Gedcom_val parsed_value) { -}*/ + struct fged_timestampable_ctxt * tctxt = NULL; + + tctxt = self; + + self = tctxt->ctxt; + free(tctxt); +} void familia_gedcom_error (Gedcom_msg_type type, char *msg) { @@ -277,9 +374,9 @@ void familia_gedcom_init() gedcom_subscribe_to_record(REC_HEAD, familia_gedcom_header_start, familia_gedcom_header_end); /* Create and set family as current (set to ctxt) */ - gedcom_subscribe_to_record(REC_FAM, familia_gedcom_family_start, NULL); + gedcom_subscribe_to_record(REC_FAM, familia_gedcom_family_start, familia_gedcom_family_end); /* Create and set individual as current (set to ctxt) */ - gedcom_subscribe_to_record(REC_INDI, familia_gedcom_individual_start, NULL); + gedcom_subscribe_to_record(REC_INDI, familia_gedcom_individual_start, familia_gedcom_individual_end); gedcom_subscribe_to_element(ELT_HEAD_SOUR, familia_gedcom_header_source_start, NULL); gedcom_subscribe_to_element(ELT_HEAD_SOUR_VERS, familia_gedcom_header_version_start, NULL); /* Set in current individual first name */ @@ -296,6 +393,9 @@ void familia_gedcom_init() gedcom_subscribe_to_element(ELT_FAM_HUSB, familia_gedcom_family_set_parent1, NULL); /* Set in current family second parent (e.g. wife) */ gedcom_subscribe_to_element(ELT_FAM_WIFE, familia_gedcom_family_set_parent2, NULL); + + gedcom_subscribe_to_element(ELT_SUB_EVT_DATE, familia_gedcom_event_set_date, NULL); + gedcom_subscribe_to_element(ELT_SUB_INDIV_BIRT, familia_gedcom_timestampable_ctxt_wrap, familia_gedcom_timestampable_ctxt_unwrap); familia_memory_stack_init(); } diff --git a/src/gedcom/familia_gedcom.h b/src/gedcom/familia_gedcom.h index 0cd88a9..d060171 100644 --- a/src/gedcom/familia_gedcom.h +++ b/src/gedcom/familia_gedcom.h @@ -22,11 +22,43 @@ #include +#include "../storage/storage.h" + /** * @file familia_gedcom.h * @brief GEDCOM Parser integration code. */ +/** + * Familia - Gedcom context. + * Used for passing current object/value between different states. + */ +struct fged_ctxt { + /** Currently parsed object, stored in storage */ + void * object; + + /** Type of current object */ + enum familia_storage_type type; +}; + +enum fged_timestamp_type { + UNSET, + + BIRTH, + +}; + +/** + * Familia - Gedcom timestampable context. + */ +struct fged_timestampable_ctxt { + /** Parent context */ + struct familia_gedcom_parser_ctxt * ctxt; + + /** Type of the timestamp */ + enum fged_timestamp_type type; +}; + /** * Initializes integration with gedcom-parse library */ diff --git a/src/math/camera.c b/src/math/camera.c index 3ab2cfc..7007524 100644 --- a/src/math/camera.c +++ b/src/math/camera.c @@ -1,6 +1,15 @@ - #include +#include "../storage/storage.h" + GLdouble camera_pos_x = 0; GLdouble camera_pos_y = 0; -GLdouble camera_pos_z = 0; \ No newline at end of file +GLdouble camera_pos_z = 0; + +/** + * + */ +struct position * camera_position_reset() +{ + /**/ +} \ No newline at end of file diff --git a/src/math/positions.c b/src/math/positions.c index 03d5b44..bf6b606 100644 --- a/src/math/positions.c +++ b/src/math/positions.c @@ -1,13 +1,72 @@ #include +#include #include "positions.h" +#include "yearline.h" #include "storage/individual.h" #include "storage/family.h" +#include "../debug.h" + +#define FAMILY_AVAIL_RANGE 180 + struct position * calculate_individual_position(struct familia_individual * individual) { -/* TODO: Implement this function*/ - return NULL; + struct position * pos = NULL; + struct familia_family * parents = NULL; + unsigned int children_no = 1; + int nth = 0; + + parents = familia_individual_get_parents(individual); + if (parents == NULL) { + debug("TODO: Calculate position for root individual."); + return NULL; + } + + nth = familia_individual_nth_child_of_family(individual, parents); + if (nth < 0) { + debug("Cannot calculate child number."); + return NULL; + } + + children_no = parents->children_no; + + if (children_no == 0) { + debug("Children number mismatch: I have child of family, " \ + "but parents does not have any children!"); + return NULL; + } + + pos = (struct position *)malloc(sizeof(struct position)); + pos->x = 0; + pos->y = 0; + pos->z = 0; + + /* If there is only one child in family, place it vertically + * over the family (do not change x and z). For all other + * calculate these positions. + */ + if (children_no != 1) { + /* Angle by which every child is rotated. */ + float theta = 0; + /* Angle by which this child will be rotated */ + float alpha = 0; + theta = FAMILY_AVAIL_RANGE / children_no; + + /* We subtract from FAMILY_AVAIL_RANGE (e.g. 180), + * to count angle from left instead of from right. + * This makes oldest children display in this order. + */ + alpha = FAMILY_AVAIL_RANGE - theta * nth; + + pos->x = cos(alpha); + pos->z = sin(alpha); + } + + /* pos.y is a local coordinate now. */ + pos->y = convert_date_to_height(NULL); + + return pos; } struct position * calculate_family_position(struct familia_family * family) diff --git a/src/storage/individual.c b/src/storage/individual.c index 33a0a08..f5a94df 100644 --- a/src/storage/individual.c +++ b/src/storage/individual.c @@ -21,6 +21,7 @@ struct familia_individual * familia_individual_new() individual->families = NULL; individual->families_no = 0; individual->parents = NULL; + individual->birth = NULL; return individual; } @@ -53,6 +54,11 @@ void familia_individual_free(struct familia_individual * individual) individual->parents = NULL; } + if (individual->birth) { + free(individual->birth); + individual->birth = NULL; + } + free(individual); } @@ -190,3 +196,33 @@ void familia_individual_remove_parents(struct familia_individual * individual) { individual->parents = NULL; } + +int familia_individual_nth_child_of_family(struct familia_individual * individual, struct familia_family * family) +{ + unsigned int i; + unsigned int children_no = family->children_no; + + for (i = 0; i < children_no; i++) { + if (family->children[i]->id == individual->id) { + return i; + } + } + + return -1; +} + +void familia_individual_set_birth_date(struct familia_individual * individual, struct date_value dv) +{ + /* TODO: Add multiple birth dates (in case there are many different sources) */ + if (!individual->birth) { + struct date_value * date = NULL; + date = gedcom_new_date_value(NULL); + + /* Just copy parsed date_value to newly allocated variable... */ + memcpy(date, &dv, sizeof(struct date_value)); + individual->birth = date; + } + else { + fprintf(stderr, "> Date has been already set, ignoring new one: %s\n", gedcom_date_to_string(&dv)); + } +} \ No newline at end of file diff --git a/src/storage/individual.h b/src/storage/individual.h index 87045c1..745698b 100644 --- a/src/storage/individual.h +++ b/src/storage/individual.h @@ -20,18 +20,26 @@ #ifndef _FAMILIA_INDIVIDUAL_H #define _FAMILIA_INDIVIDUAL_H +#include + #include "family.h" +/** + * @file storage/individual.h + * @brief Code for managing individuals from the family. + * + */ + /** * Structure holding individual data. */ struct familia_individual { /** Individual identifier */ unsigned int id; - + /** Individual first name */ char * first_name; - + /** Individual last name */ char * last_name; @@ -43,6 +51,13 @@ struct familia_individual { /** Parent family. Family this individual comes from. */ struct familia_family * parents; + + /** + * Birth date of individual. + * Could be exact date, range or unrecognized. You can find more info in + * gedcom-parse documentation. + */ + struct date_value * birth; }; /** @@ -54,51 +69,51 @@ struct familia_individual * familia_individual_new(); /** * Frees allocated memory of the given individual - * DISCLAIMER! This function does not free memory of linked families. You have to - * remove them manually from storage. - * @parameter individual to free + * @attention This function does not free memory of linked families. You have to + * remove them manually from @ref familia_storage, by using @ref familia_storage_free. + * @param individual individual to free */ void familia_individual_free(struct familia_individual * individual); /** * Sets first name of the given individual - * @parameter individual to set first name - * @parameter first name to set + * @param individual individual to set first name + * @param first_name first name to set */ void familia_individual_set_first_name(struct familia_individual * individual, char * first_name); /** * Gets first name of the given individual - * @parameter individual from whom get the first name + * @param individual individual from whom get the first name * @return individuals first name */ char * familia_individual_get_first_name(struct familia_individual * individual); /** * Sets last name of the given individual - * @parameter individual to set last name - * @parameter last name to set + * @param individual individual to set last name + * @param last_name last name to set */ void familia_individual_set_last_name(struct familia_individual * individual, char * last_name); /** * Gets last name of the given individual - * @parameter individual from whom get the last name + * @param individual individual from whom get the last name * @return individuals last name */ char * familia_individual_get_last_name(struct familia_individual * individual); /** * Adds family to the given individual - * @parameter individual to set last name - * @parameter last name to set + * @param individual individual to set last name + * @param family last name to set */ void familia_individual_add_family(struct familia_individual * individual, struct familia_family * family); /** * Gets family with the given id of the given individual - * @parameter individual from whom get the family - * @parameter family id of the individual + * @param individual individual from whom get the family + * @param id family id of the individual * @return selected family or NULL if such does not exists or index is out of * array bounds */ @@ -108,22 +123,21 @@ struct familia_family * familia_individual_get_family_by_id(struct familia_indiv * Removes family with the given id from the given individual * DISCLAIMER! This function does not free memory of linked families. You have to * remove them manually from storage. - * @parameter individual from whom family will be removed - * @parameter family id of the individual + * @param individual individual from whom family will be removed + * @param id family id of the individual */ void familia_individual_remove_family_by_id(struct familia_individual * individual, unsigned int id); /** * Sets parents family of the given individual - * @parameter individual to set parents - * @parameter parents to set + * @param individual individual to set parents + * @param family parents to set */ void familia_individual_set_parents(struct familia_individual * individual, struct familia_family * family); /** * Gets family with the given id of the given individual - * @parameter individual from whom get the family - * @parameter family id of the individual + * @param individual individual from whom get the parents * @return individuals last name */ struct familia_family * familia_individual_get_parents(struct familia_individual * individual); @@ -132,8 +146,24 @@ struct familia_family * familia_individual_get_parents(struct familia_individual * Removes parents from the given individual * DISCLAIMER! This function does not free memory of linked family. You have to * remove them manually from storage. - * @parameter individual from whom parents will be removed + * @param individual individual from whom parents will be removed */ void familia_individual_remove_parents(struct familia_individual * individual); +/** + * Calculates family number in order + * @return child number of individual in the given family, -1 on error or if child does not belong to family. + */ +int familia_individual_nth_child_of_family(struct familia_individual * individual, struct familia_family * family); + +/** + * Sets individual birth date. + * Date value is copied individual. Value is released on individual free(). + * @see familia_individual_free + * @param individual individual to set birth date + * @param dv date of the birth (exact, or bounds) + * @return child number of individual in the given family, -1 on error or if child does not belong to family. + */ +void familia_individual_set_birth_date(struct familia_individual * individual, struct date_value dv); + #endif /*_FAMILIA_INDIVIDUAL_H */ diff --git a/src/storage/positions.c b/src/storage/positions.c index e628997..8cb8ebe 100644 --- a/src/storage/positions.c +++ b/src/storage/positions.c @@ -19,6 +19,7 @@ #include #include +#include #include "../debug.h" @@ -229,5 +230,4 @@ struct position * familia_position_get_family_position(struct familia_family *fa * Entry not found for a given individual. Return error. */ return NULL; -} - +} \ No newline at end of file diff --git a/src/storage/storage.h b/src/storage/storage.h index 8800399..b72121b 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -68,7 +68,7 @@ struct familia_storage * familia_storage_get_current(); /** * Sets storage structure as a currently loaded one. - * @parameter storage to set as a current one + * @param storage storage to set as a current one */ void familia_storage_set_current(struct familia_storage * storage); @@ -81,51 +81,51 @@ struct familia_storage * familia_storage_new(); /** * Frees storage and all the content in it - * @parameter storage to free + * @param storage storage to free */ void familia_storage_free(struct familia_storage * storage); /** * Adds individual to the storage - * @parameter storage to which add individual - * @parameter individual to add to the storage + * @param storage storage to which add individual + * @param individual individual to add to the storage */ void familia_storage_add_individual(struct familia_storage * storage, struct familia_individual * individual); /** * Gets individual with the given id from the storage - * @parameter storage from which search for individual - * @parameter individual identifier + * @param storage storage from which search for individual + * @param id individual identifier * @return loaded individual if found. NULL otherwise. */ struct familia_individual * familia_storage_get_individual_by_id(struct familia_storage * storage, unsigned int id); /** * Removes individual with the given id from the storage - * @parameter storage from which remove individual - * @parameter individual id + * @param storage storage from which remove individual + * @param id individual id */ void familia_storage_remove_individual_by_id(struct familia_storage * storage, unsigned int id); /** * Adds family to the storage - * @parameter storage to which add family - * @parameter family to add to the storage + * @param storage storage to which add family + * @param family family to add to the storage */ void familia_storage_add_family(struct familia_storage * storage, struct familia_family * family); /** * Gets family with the given id from the storage - * @parameter storage from which search for family - * @parameter family identifier + * @param storage storage from which search for family + * @param id family identifier * @return loaded family if found. NULL otherwise */ struct familia_family * familia_storage_get_family_by_id(struct familia_storage * storage, unsigned int id); /** * Removes family with the given id from the storage - * @parameter storage from which remove family - * @parameter family id + * @param storage storage from which remove family + * @param id family id */ void familia_storage_remove_family_by_id(struct familia_storage * storage, unsigned int id); -- 2.30.2