Made GsweAspectData a refcounted boxed type
This is to satisfy #7, but it also satisfies #8, as gswe_init() is called where data initialized there is necessary.
This commit is contained in:
parent
7564183aa2
commit
dbee248a6e
@ -134,7 +134,13 @@ gswe_aspect_info_get_type
|
||||
<SECTION>
|
||||
<FILE>gswe-aspect-data</FILE>
|
||||
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
|
||||
|
@ -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__ */
|
||||
|
@ -15,8 +15,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user