diff --git a/docs/reference/swe-glib/swe-glib-sections.txt b/docs/reference/swe-glib/swe-glib-sections.txt index c1f75ee..99b2d8a 100644 --- a/docs/reference/swe-glib/swe-glib-sections.txt +++ b/docs/reference/swe-glib/swe-glib-sections.txt @@ -134,7 +134,13 @@ gswe_aspect_info_get_type
gswe-aspect-data GsweAspectData +gswe_aspect_data_new +gswe_aspect_data_new_with_planets +gswe_aspect_data_ref +gswe_aspect_data_unref +gswe_aspect_data_set_planet1 gswe_aspect_data_get_planet1 +gswe_aspect_data_set_planet2 gswe_aspect_data_get_planet2 gswe_aspect_data_get_distance gswe_aspect_data_get_aspect diff --git a/src/gswe-aspect-data-private.h b/src/gswe-aspect-data-private.h index 631a636..fa8ffef 100644 --- a/src/gswe-aspect-data-private.h +++ b/src/gswe-aspect-data-private.h @@ -32,17 +32,17 @@ struct _GsweAspectData { /* the distance between the two planets, in degrees */ gdouble distance; - /* the aspect between the two planets */ - GsweAspect aspect; - /* the #GsweAspectInfo structure associated with the aspect */ GsweAspectInfo *aspect_info; /* the difference in percent between an exact aspect and this given aspect */ gdouble difference; + + /* reference count */ + guint refcount; }; -GsweAspectData *gswe_aspect_data_copy(GsweAspectData *aspect_data); +void gswe_aspect_data_calculate(GsweAspectData *aspect_data); #endif /* __SWE_GLIB_GSWE_ASPECT_DATA_PRIVATE_H__ */ #else /* not defined __SWE_GLIB_BUILDING__ */ diff --git a/src/gswe-aspect-data.c b/src/gswe-aspect-data.c index 354128c..492e5ea 100644 --- a/src/gswe-aspect-data.c +++ b/src/gswe-aspect-data.c @@ -15,8 +15,15 @@ * You should have received a copy of the GNU General Public License * along with this library; if not, see . */ +#include #include +#include "swe-glib-private.h" +#include "swe-glib.h" +#include "gswe-planet-data-private.h" +#include "gswe-planet-info-private.h" +#include "gswe-aspect-info.h" +#include "gswe-aspect-info-private.h" #include "gswe-aspect-data.h" #include "gswe-aspect-data-private.h" @@ -31,32 +38,164 @@ * #GsweAspectData is a structure that represents two planets relation to each * other, like their aspect and the aspect's difference from an exact aspect. */ -G_DEFINE_BOXED_TYPE(GsweAspectData, gswe_aspect_data, (GBoxedCopyFunc)gswe_aspect_data_copy, (GBoxedFreeFunc)g_free); +G_DEFINE_BOXED_TYPE(GsweAspectData, gswe_aspect_data, (GBoxedCopyFunc)gswe_aspect_data_ref, (GBoxedFreeFunc)gswe_aspect_data_unref); +static void +gswe_aspect_data_free(GsweAspectData *aspect_data) +{ + if (aspect_data->planet1) { + gswe_planet_data_unref(aspect_data->planet1); + } + + if (aspect_data->planet2) { + gswe_planet_data_unref(aspect_data->planet2); + } + + if (aspect_data->aspect_info) { + gswe_aspect_info_unref(aspect_data->aspect_info); + } + + g_free(aspect_data); +} + +static gboolean +find_aspect(gpointer aspect_p, GsweAspectInfo *aspect_info, GsweAspectData *aspect_data) +{ + gdouble diff, + planet_orb, + aspect_orb; + + diff = fabs(aspect_info->size - aspect_data->distance); + planet_orb = fmin(aspect_data->planet1->planet_info->orb, aspect_data->planet2->planet_info->orb); + aspect_orb = fmax(1.0, planet_orb - aspect_info->orb_modifier); + + if (diff < aspect_orb) { + aspect_data->aspect_info = gswe_aspect_info_ref(aspect_info); + + if (aspect_info->size == 0) { + aspect_data->difference = (1 - ((360.0 - diff) / 360.0)) * 100.0; + } else { + aspect_data->difference = (1 - ((aspect_info->size - diff) / aspect_info->size)) * 100.0; + } + + return TRUE; + } + + return FALSE; +} + +void +gswe_aspect_data_calculate(GsweAspectData *aspect_data) +{ + GsweAspectInfo *aspect_info; + + if ((aspect_data->distance = fabs(aspect_data->planet1->position - aspect_data->planet2->position)) > 180.0) { + aspect_data->distance = 360.0 - aspect_data->distance; + } + + if ((aspect_info = g_hash_table_find(gswe_aspect_info_table, (GHRFunc)find_aspect, aspect_data)) == NULL) { + aspect_data->aspect_info = gswe_aspect_info_ref(g_hash_table_lookup(gswe_aspect_info_table, GINT_TO_POINTER(GSWE_ASPECT_NONE))); + } +} + +/** + * gswe_aspect_data_new: + * + * Creates a new #GsweAspectData with reference count set to 1. + * + * Returns: (transfer full): a new #GsweAspectData + */ GsweAspectData * -gswe_aspect_data_copy(GsweAspectData *aspect_data) +gswe_aspect_data_new(void) { GsweAspectData *ret; - if (aspect_data == NULL) { - return NULL; - } + gswe_init(); ret = g_new0(GsweAspectData, 1); - - ret->planet1 = aspect_data->planet1; - ret->planet2 = aspect_data->planet2; - ret->distance = aspect_data->distance; - ret->aspect = aspect_data->aspect; - ret->aspect_info = aspect_data->aspect_info; - ret->difference = aspect_data->difference; + ret->refcount = 1; return ret; } +/** + * gswe_aspect_data_new_with_planets: + * @planet1: (in): a #GswePlanetData + * @planet2: (in): a #GswePlanetData + * + * Creates a new #GsweAspectData with a reference count of 1, and both planets + * initially set. Also calculates the aspect between them. + * + * Returns: (transfer full): a new #GsweAspectData with all data set. + */ +GsweAspectData * +gswe_aspect_data_new_with_planets(GswePlanetData *planet1, GswePlanetData *planet2) +{ + GsweAspectData *ret; + + ret = gswe_aspect_data_new(); + ret->planet1 = gswe_planet_data_ref(planet1); + ret->planet2 = gswe_planet_data_ref(planet2); + + gswe_aspect_data_calculate(ret); + + return ret; +} + +/** + * gswe_aspect_data_ref: + * @aspect_data: a #GsweAspectData + * + * Increases reference count of @aspect_data. + * + * Returns: (transfer none): the same #GsweAspectData + */ +GsweAspectData * +gswe_aspect_data_ref(GsweAspectData *aspect_data) +{ + aspect_data->refcount++; + + return aspect_data; +} + +/** + * gswe_aspect_data_unref: + * @aspect_data: (in): a #GsweAspectData + * + * Decreases reference count on @aspect_data. If reference count reaches zero, @aspect_data is freed. + */ +void +gswe_aspect_data_unref(GsweAspectData *aspect_data) +{ + if (--aspect_data->refcount == 0) { + gswe_aspect_data_free(aspect_data); + } +} + +/** + * gswe_aspect_data_set_planet1: + * @aspect_data: (in): a #GsweAspectData + * @planet1: (in): a #GswePlanetData + * + * Sets @planet1 as the first planet of the aspect. + */ +void +gswe_aspect_data_set_planet1(GsweAspectData *aspect_data, GswePlanetData *planet1) +{ + if (aspect_data->planet1) { + gswe_planet_data_unref(aspect_data->planet1); + } + + aspect_data->planet1 = gswe_planet_data_ref(planet1); + + if (aspect_data->planet2) { + gswe_aspect_data_calculate(aspect_data); + } +} + /** * gswe_aspect_data_get_planet1: - * @aspect_data: (in) (allow-none): a #GsweAspectData + * @aspect_data: (in): a #GsweAspectData * * Gets the first planet in the aspect. * @@ -65,16 +204,33 @@ gswe_aspect_data_copy(GsweAspectData *aspect_data) GswePlanetData * gswe_aspect_data_get_planet1(GsweAspectData *aspect_data) { - if (aspect_data) { - return aspect_data->planet1; - } else { - return NULL; + return aspect_data->planet1; +} + +/** + * gswe_aspect_data_set_planet2: + * @aspect_data: (in): a #GsweAspectData + * @planet2: (in): a #GswePlanetData + * + * Sets @planet2 as the second planet of the aspect. + */ +void +gswe_aspect_data_set_planet2(GsweAspectData *aspect_data, GswePlanetData *planet2) +{ + if (aspect_data->planet2) { + gswe_planet_data_unref(aspect_data->planet2); + } + + aspect_data->planet2 = gswe_planet_data_ref(planet2); + + if (aspect_data->planet1) { + gswe_aspect_data_calculate(aspect_data); } } /** * gswe_aspect_data_get_planet2: - * @aspect_data: (in) (allow-none): a #GsweAspectData + * @aspect_data: (in): a #GsweAspectData * * Gets the second planet in the aspect. * @@ -92,7 +248,7 @@ gswe_aspect_data_get_planet2(GsweAspectData *aspect_data) /** * gswe_aspect_data_get_distance: - * @aspect_data: (in) (allow-none): a #GsweAspectData + * @aspect_data: (in): a #GsweAspectData * * Gets the exact distance between the two planets in the aspect. * @@ -110,7 +266,7 @@ gswe_aspect_data_get_distance(GsweAspectData *aspect_data) /** * gswe_aspect_data_get_aspect: - * @aspect_data: (in) (allow-none): a #GsweAspectData + * @aspect_data: (in): a #GsweAspectData * * Gets the actual aspect between the two planets. * @@ -119,8 +275,8 @@ gswe_aspect_data_get_distance(GsweAspectData *aspect_data) GsweAspect gswe_aspect_data_get_aspect(GsweAspectData *aspect_data) { - if (aspect_data) { - return aspect_data->aspect; + if (aspect_data->aspect_info) { + return aspect_data->aspect_info->aspect; } else { return GSWE_ASPECT_NONE; } @@ -128,7 +284,7 @@ gswe_aspect_data_get_aspect(GsweAspectData *aspect_data) /** * gswe_aspect_data_get_aspect_info: - * @aspect_data: (in) (allow-none): a #GsweAspectData + * @aspect_data: (in): a #GsweAspectData * * Gets the the #GsweAspectInfo object for this aspect. * @@ -146,7 +302,7 @@ gswe_aspect_data_get_aspect_info(GsweAspectData *aspect_data) /** * gswe_aspect_data_get_difference: - * @aspect_data: (in) (allow-none): a #GsweAspectData + * @aspect_data: (in): a #GsweAspectData * * Gets the difference between an exact aspect and this one. * diff --git a/src/gswe-aspect-data.h b/src/gswe-aspect-data.h index ec9aebd..079e9c4 100644 --- a/src/gswe-aspect-data.h +++ b/src/gswe-aspect-data.h @@ -39,8 +39,18 @@ typedef struct _GsweAspectData GsweAspectData; GType gswe_aspect_data_get_type(void); #define GSWE_TYPE_ASPECT_DATA (gswe_aspect_data_get_type()) +GsweAspectData *gswe_aspect_data_new(void); +GsweAspectData *gswe_aspect_data_new_with_planets(GswePlanetData *planet1, GswePlanetData *planet2); + +GsweAspectData *gswe_aspect_data_ref(GsweAspectData *aspect_data); +void gswe_aspect_data_unref(GsweAspectData *aspect_data); + +void gswe_aspect_data_set_planet1(GsweAspectData *aspect_data, GswePlanetData *planet1); GswePlanetData *gswe_aspect_data_get_planet1(GsweAspectData *aspect_data); + +void gswe_aspect_data_set_planet2(GsweAspectData *aspect_data, GswePlanetData *planet2); GswePlanetData *gswe_aspect_data_get_planet2(GsweAspectData *aspect_data); + gdouble gswe_aspect_data_get_distance(GsweAspectData *aspect_data); GsweAspect gswe_aspect_data_get_aspect(GsweAspectData *aspect_data); GsweAspectInfo *gswe_aspect_data_get_aspect_info(GsweAspectData *aspect_data); diff --git a/src/gswe-moment.c b/src/gswe-moment.c index 3e610f6..b041203 100644 --- a/src/gswe-moment.c +++ b/src/gswe-moment.c @@ -202,6 +202,7 @@ gswe_moment_finalize(GObject *gobject) g_list_free_full(moment->priv->house_list, g_free); g_list_free_full(moment->priv->planet_list, g_free); + g_list_free_full(moment->priv->aspect_list, (GDestroyNotify)gswe_aspect_data_unref); G_OBJECT_CLASS(gswe_moment_parent_class)->finalize(gobject); } @@ -1025,40 +1026,6 @@ find_aspect_by_both_planets(GsweAspectData *aspect, struct GsweAspectFinder *asp return 1; } -static gboolean -find_aspect(gpointer aspect_p, GsweAspectInfo *aspect_info, GsweAspectData *aspect_data) -{ - GsweAspect aspect = GPOINTER_TO_INT(aspect_p); - gdouble diff, - planet_orb, - aspect_orb; - - aspect_data->distance = fabs(aspect_data->planet1->position - aspect_data->planet2->position); - - if (aspect_data->distance > 180.0) { - aspect_data->distance = 360.0 - aspect_data->distance; - } - - diff = fabs(aspect_info->size - aspect_data->distance); - planet_orb = fmin(aspect_data->planet1->planet_info->orb, aspect_data->planet2->planet_info->orb); - aspect_orb = fmax(1.0, planet_orb - aspect_info->orb_modifier); - - if (diff < aspect_orb) { - aspect_data->aspect = aspect; - aspect_data->aspect_info = aspect_info; - - if (aspect_info->size == 0) { - aspect_data->difference = (1 - ((360.0 - diff) / 360.0)) * 100.0; - } else { - aspect_data->difference = (1 - ((aspect_info->size - diff) / aspect_info->size)) * 100.0; - } - - return TRUE; - } - - return FALSE; -} - static void gswe_moment_calculate_aspects(GsweMoment *moment) { @@ -1070,7 +1037,7 @@ gswe_moment_calculate_aspects(GsweMoment *moment) } gswe_moment_calculate_all_planets(moment); - g_list_free_full(moment->priv->aspect_list, g_free); + g_list_free_full(moment->priv->aspect_list, (GDestroyNotify)gswe_aspect_data_unref); moment->priv->aspect_list = NULL; for (oplanet = moment->priv->planet_list; oplanet; oplanet = oplanet->next) { @@ -1079,30 +1046,21 @@ gswe_moment_calculate_aspects(GsweMoment *moment) *inner_planet = iplanet->data; struct GsweAspectFinder aspect_finder; GsweAspectData *aspect_data; + GList *aspect_data_element; - if (outer_planet->planet == inner_planet->planet) { + if (outer_planet->planet_info->planet == inner_planet->planet_info->planet) { continue; } - aspect_finder.planet1 = outer_planet->planet; - aspect_finder.planet2 = inner_planet->planet; + aspect_finder.planet1 = outer_planet->planet_info->planet; + aspect_finder.planet2 = inner_planet->planet_info->planet; - if (g_list_find_custom(moment->priv->aspect_list, &aspect_finder, (GCompareFunc)find_aspect_by_both_planets) != NULL) { - continue; + if ((aspect_data_element = g_list_find_custom(moment->priv->aspect_list, &aspect_finder, (GCompareFunc)find_aspect_by_both_planets)) != NULL) { + gswe_aspect_data_calculate(aspect_data_element->data); + } else { + aspect_data = gswe_aspect_data_new_with_planets(inner_planet, outer_planet); + moment->priv->aspect_list = g_list_prepend(moment->priv->aspect_list, aspect_data); } - - aspect_data = g_new0(GsweAspectData, 1); - aspect_data->planet1 = outer_planet; - aspect_data->planet2 = inner_planet; - aspect_data->aspect = GSWE_ASPECT_NONE; - - (void)g_hash_table_find(gswe_aspect_info_table, (GHRFunc)find_aspect, aspect_data); - - if (aspect_data->aspect == GSWE_ASPECT_NONE) { - aspect_data->aspect_info = g_hash_table_lookup(gswe_aspect_info_table, GINT_TO_POINTER(GSWE_ASPECT_NONE)); - } - - moment->priv->aspect_list = g_list_prepend(moment->priv->aspect_list, aspect_data); } }