Fixed documentation.
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 \
$(GLU_LIBS) \
@GEDCOM_LIBS@ \
-L/usr/lib \
- -lzip
+ -lzip -lm
bin_familia_LDFLAGS = $(LTLIBINTL)
#include "../storage/individual.h"
#include "../memory_stack.h"
+#include "../debug.h"
+
Gedcom_ctxt familia_gedcom_header_start (Gedcom_rec rec,
int level,
Gedcom_val xref,
int parsed_tag,
Gedcom_val parsed_value)
{
+ assert(rec == REC_HEAD);
+
fprintf(stderr, "The header starts (l: %d, tag: %s, raw:%s) \n", level, tag, raw_value);
return (Gedcom_ctxt)1;
}
-void familia_gedcom_header_end (Gedcom_rec rec, Gedcom_ctxt self)
+void familia_gedcom_header_end (Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value)
{
/* context will print as "1" */
fprintf(stderr, "The header ends, context is %d\n", (int)self);
struct familia_family * family = NULL;
struct xref_value *xr = GEDCOM_XREF_PTR(xref);
+ assert(rec == REC_FAM);
+ assert(parsed_tag == TAG_FAM);
+
family = familia_memory_stack_find(xr->string, 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,
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,
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;
}
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));
}
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);
{
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);
{
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);
{
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 */
{
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 */
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)
{
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 */
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();
}
#include <gedcom.h>
+#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
*/
-
#include <GL/gl.h>
+#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
#include <stdlib.h>
+#include <math.h>
#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)
individual->families = NULL;
individual->families_no = 0;
individual->parents = NULL;
+ individual->birth = NULL;
return individual;
}
individual->parents = NULL;
}
+ if (individual->birth) {
+ free(individual->birth);
+ individual->birth = NULL;
+ }
+
free(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
#ifndef _FAMILIA_INDIVIDUAL_H
#define _FAMILIA_INDIVIDUAL_H
+#include <gedcom.h>
+
#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;
/** 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;
};
/**
/**
* 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
*/
* 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);
* 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 */
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
#include "../debug.h"
* Entry not found for a given individual. Return error.
*/
return NULL;
-}
-
+}
\ No newline at end of file
/**
* 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);
/**
* 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);