Extend LdPointArray.

This commit is contained in:
Přemysl Eric Janouch 2011-02-02 19:30:06 +01:00
parent f864693f1b
commit 75c2358b69
5 changed files with 150 additions and 30 deletions

View File

@ -1064,7 +1064,7 @@ check_terminals (LdCanvas *self, gdouble x, gdouble y)
LdDiagramSymbol *diagram_symbol; LdDiagramSymbol *diagram_symbol;
LdSymbol *symbol; LdSymbol *symbol;
const LdPointArray *terminals; const LdPointArray *terminals;
gint i; guint i;
if (!LD_IS_DIAGRAM_SYMBOL (iter->data)) if (!LD_IS_DIAGRAM_SYMBOL (iter->data))
continue; continue;
@ -1079,7 +1079,7 @@ check_terminals (LdCanvas *self, gdouble x, gdouble y)
terminals = ld_symbol_get_terminals (symbol); terminals = ld_symbol_get_terminals (symbol);
for (i = 0; i < terminals->num_points; i++) for (i = 0; i < terminals->length; i++)
{ {
LdPoint cur_term; LdPoint cur_term;
gdouble distance; gdouble distance;

View File

@ -168,22 +168,23 @@ ld_diagram_connection_get_points (LdDiagramConnection *self)
storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (self)); storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (self));
node = json_object_get_member (storage, "points"); node = json_object_get_member (storage, "points");
if (!node || json_node_is_null (node)) if (!node || json_node_is_null (node))
return ld_point_array_new (0); return ld_point_array_new ();
if (!JSON_NODE_HOLDS_ARRAY (node)) if (!JSON_NODE_HOLDS_ARRAY (node))
{ {
WARN_NODE_TYPE (node, LD_TYPE_POINT_ARRAY); WARN_NODE_TYPE (node, LD_TYPE_POINT_ARRAY);
return ld_point_array_new (0); return ld_point_array_new ();
} }
array = json_node_get_array (node); array = json_node_get_array (node);
point_node_list = json_array_get_elements (array); point_node_list = json_array_get_elements (array);
points = ld_point_array_new (json_array_get_length (array)); points = ld_point_array_sized_new (json_array_get_length (array));
points->num_points = 0;
for (iter = point_node_list; iter; iter = g_list_next (iter)) for (iter = point_node_list; iter; iter = g_list_next (iter))
{ {
if (read_point_node (iter->data, &points->points[points->num_points])) g_assert (points->length < points->size);
points->num_points++;
if (read_point_node (iter->data, &points->points[points->length]))
points->length++;
} }
return points; return points;
} }
@ -267,7 +268,7 @@ ld_diagram_connection_set_points (LdDiagramConnection *self,
storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (self)); storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (self));
array = json_array_new (); array = json_array_new ();
for (i = 0; i < points->num_points; i++) for (i = 0; i < points->length; i++)
{ {
point_array = json_array_new (); point_array = json_array_new ();
json_array_add_double_element (point_array, points->points[i].x); json_array_add_double_element (point_array, points->points[i].x);

View File

@ -576,15 +576,14 @@ read_terminals (lua_State *L, int index, LdPointArray **terminals)
{ {
LdPointArray *points; LdPointArray *points;
size_t num_points; size_t num_points;
unsigned i = 0;
num_points = lua_objlen (L, index); num_points = lua_objlen (L, index);
points = ld_point_array_new (num_points); points = ld_point_array_sized_new (num_points);
lua_pushnil (L); lua_pushnil (L);
while (lua_next (L, index) != 0) while (lua_next (L, index) != 0)
{ {
g_assert (i < num_points); g_assert (points->length < points->size);
if (!lua_istable (L, -1) || lua_objlen (L, -1) != 2) if (!lua_istable (L, -1) || lua_objlen (L, -1) != 2)
goto read_terminals_fail; goto read_terminals_fail;
@ -592,16 +591,16 @@ read_terminals (lua_State *L, int index, LdPointArray **terminals)
lua_rawgeti (L, -1, 1); lua_rawgeti (L, -1, 1);
if (!lua_isnumber (L, -1)) if (!lua_isnumber (L, -1))
goto read_terminals_fail; goto read_terminals_fail;
points->points[i].x = lua_tonumber (L, -1); points->points[points->length].x = lua_tonumber (L, -1);
lua_pop (L, 1); lua_pop (L, 1);
lua_rawgeti (L, -1, 2); lua_rawgeti (L, -1, 2);
if (!lua_isnumber (L, -1)) if (!lua_isnumber (L, -1))
goto read_terminals_fail; goto read_terminals_fail;
points->points[i].y = lua_tonumber (L, -1); points->points[points->length].y = lua_tonumber (L, -1);
lua_pop (L, 2); lua_pop (L, 2);
i++; points->length++;
} }
*terminals = points; *terminals = points;
return TRUE; return TRUE;

View File

@ -9,6 +9,7 @@
*/ */
#include <math.h> #include <math.h>
#include <string.h>
#include "liblogdiag.h" #include "liblogdiag.h"
#include "config.h" #include "config.h"
@ -102,22 +103,34 @@ ld_point_distance (LdPoint *self, gdouble x, gdouble y)
/** /**
* ld_point_array_new: * ld_point_array_new:
* @num_points: the number of points the array can store.
* *
* Create a new array of points and initialize. * Create a new #LdPointArray.
* *
* Return value: an #LdPointArray structure. * Return value: (transfer full): an #LdPointArray structure.
*/ */
LdPointArray * LdPointArray *
ld_point_array_new (gint num_points) ld_point_array_new (void)
{
return ld_point_array_sized_new (0);
}
/**
* ld_point_array_sized_new:
* @preallocated: the number of points preallocated.
*
* Create a new #LdPointArray and preallocate storage for @preallocated items.
*
* Return value: (transfer full): an #LdPointArray structure.
*/
LdPointArray *
ld_point_array_sized_new (guint preallocated)
{ {
LdPointArray *new_array; LdPointArray *new_array;
g_return_val_if_fail (num_points >= 1, NULL);
new_array = g_slice_new (LdPointArray); new_array = g_slice_new (LdPointArray);
new_array->num_points = num_points; new_array->length = 0;
new_array->points = g_malloc0 (num_points * sizeof (LdPoint)); new_array->size = preallocated;
new_array->points = g_malloc0 (preallocated * sizeof (LdPoint));
return new_array; return new_array;
} }
@ -128,7 +141,7 @@ ld_point_array_new (gint num_points)
* Makes a copy of the structure. * Makes a copy of the structure.
* The result must be freed by ld_point_array_free(). * The result must be freed by ld_point_array_free().
* *
* Return value: a copy of @self. * Return value: (transfer full): a copy of @self.
*/ */
LdPointArray * LdPointArray *
ld_point_array_copy (const LdPointArray *self) ld_point_array_copy (const LdPointArray *self)
@ -138,9 +151,9 @@ ld_point_array_copy (const LdPointArray *self)
g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (self != NULL, NULL);
new_array = g_slice_new (LdPointArray); new_array = g_slice_new (LdPointArray);
new_array->num_points = self->num_points; new_array->length = self->length;
new_array->points = g_memdup (self->points, new_array->size = self->size;
self->num_points * sizeof (LdPoint)); new_array->points = g_memdup (self->points, self->size * sizeof (LdPoint));
return new_array; return new_array;
} }
@ -159,6 +172,106 @@ ld_point_array_free (LdPointArray *self)
g_slice_free (LdPointArray, self); g_slice_free (LdPointArray, self);
} }
/**
* ld_point_array_insert:
* @self: an #LdPointArray structure.
* @points: an array of points to be inserted.
* @pos: the position at which the points should be inserted. This number
* must not be bigger than the number of points already present
* in the array. Negative values append to the array.
* @length: count of points in @points.
*
* Insert points into the array.
*/
void
ld_point_array_insert (LdPointArray *self, LdPoint *points,
gint pos, guint length)
{
guint new_size;
g_return_if_fail (self != NULL);
g_return_if_fail (points != NULL);
g_return_if_fail (pos <= (signed) self->length);
new_size = self->size ? self->size : 1;
while (self->length + length > new_size)
new_size <<= 1;
if (new_size != self->size)
ld_point_array_set_size (self, new_size);
if (pos < 0)
pos = self->length;
g_memmove (self->points + pos + length, self->points + pos,
(self->length - pos) * sizeof (LdPoint));
memcpy (self->points + pos, points, length * sizeof (LdPoint));
self->length += length;
}
/**
* ld_point_array_remove:
* @self: an #LdPointArray structure.
* @pos: the position at which the points should be removed.
* Negative values are relative to the end of the array.
* @length: count of points to remove.
*
* Remove points from the array. The array may be resized as a result.
*/
void
ld_point_array_remove (LdPointArray *self, gint pos, guint length)
{
guint new_size;
g_return_if_fail (self != NULL);
if (pos < 0)
{
pos += self->length;
if (pos < 0)
{
length += pos;
pos = 0;
}
}
if ((unsigned) pos >= self->length)
return;
if (pos + length > self->length)
length = self->length - pos;
g_memmove (self->points + pos, self->points + pos + length,
(self->length - pos) * sizeof (LdPoint));
self->length -= length;
new_size = self->size;
while (new_size >> 2 > self->length)
new_size >>= 1;
if (new_size != self->size)
ld_point_array_set_size (self, new_size);
}
/**
* ld_point_array_set_size:
* @self: an #LdPointArray structure.
* @size: the new size.
*
* Change size of the array.
*/
void ld_point_array_set_size (LdPointArray *self, guint size)
{
g_return_if_fail (self != NULL);
if (self->size == size)
return;
self->points = g_realloc (self->points, size * sizeof (LdPoint));
if (self->length > size)
self->length = size;
if (self->size < size)
memset (self->points + self->length, 0, size - self->length);
self->size = size;
}
/** /**
* ld_rectangle_copy: * ld_rectangle_copy:
* @self: an #LdRectangle structure. * @self: an #LdRectangle structure.

View File

@ -45,21 +45,28 @@ gdouble ld_point_distance (LdPoint *self, gdouble x, gdouble y);
/** /**
* LdPointArray: * LdPointArray:
* @points: an array of #LdPoint structures. * @points: an array of #LdPoint structures.
* @num_points: count of points in @points. * @length: count of points in @points.
* @size: how many points can be stored in @points.
* *
* Defines an array of points. * Defines an array of points.
*/ */
struct _LdPointArray struct _LdPointArray
{ {
LdPoint *points; LdPoint *points;
gint num_points; guint length;
guint size;
}; };
GType ld_point_array_get_type (void) G_GNUC_CONST; GType ld_point_array_get_type (void) G_GNUC_CONST;
LdPointArray *ld_point_array_new (gint num_points); LdPointArray *ld_point_array_new (void);
LdPointArray *ld_point_array_sized_new (guint preallocated);
LdPointArray *ld_point_array_copy (const LdPointArray *self); LdPointArray *ld_point_array_copy (const LdPointArray *self);
void ld_point_array_free (LdPointArray *self); void ld_point_array_free (LdPointArray *self);
void ld_point_array_insert (LdPointArray *self, LdPoint *points,
gint pos, guint length);
void ld_point_array_remove (LdPointArray *self, gint pos, guint length);
void ld_point_array_set_size (LdPointArray *self, guint size);
/** /**