forked from AuroraMiddleware/gtk
add GtkArray
Try to use stack space if we can and only fall back to the GPtrArray if we must.
This commit is contained in:
parent
aaecb3d84b
commit
0c4dcd9d57
100
gtk/gtkarrayimplprivate.h
Normal file
100
gtk/gtkarrayimplprivate.h
Normal file
@ -0,0 +1,100 @@
|
||||
#ifndef __GTK_ARRAY_IMPL_PRIVATE_H__
|
||||
#define __GTK_ARRAY_IMPL_PRIVATE_H__
|
||||
|
||||
|
||||
/* This is a dumbed-down GPtrArray, which takes some stack
|
||||
* space to use. When using this, the general case should always
|
||||
* be that the number of elements is lower than reversed_size.
|
||||
* The GPtrArray should only be used in extreme cases.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint reserved_size;
|
||||
guint len;
|
||||
void **stack_space;
|
||||
GPtrArray *ptr_array;
|
||||
|
||||
} GtkArray;
|
||||
|
||||
|
||||
static inline void
|
||||
gtk_array_init (GtkArray *self,
|
||||
void **stack_space,
|
||||
guint reserved_size)
|
||||
{
|
||||
self->reserved_size = reserved_size;
|
||||
self->len = 0;
|
||||
self->stack_space = stack_space;
|
||||
self->ptr_array = NULL;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
gtk_array_index (GtkArray *self,
|
||||
guint index)
|
||||
{
|
||||
g_assert (index < self->len);
|
||||
|
||||
if (G_LIKELY (!self->ptr_array))
|
||||
return self->stack_space[index];
|
||||
|
||||
return g_ptr_array_index (self->ptr_array, index);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gtk_array_add (GtkArray *self,
|
||||
void *element)
|
||||
{
|
||||
if (G_LIKELY (self->len < self->reserved_size))
|
||||
{
|
||||
self->stack_space[self->len] = element;
|
||||
self->len++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to fall back to the GPtrArray */
|
||||
if (G_UNLIKELY (!self->ptr_array))
|
||||
{
|
||||
guint i;
|
||||
|
||||
self->ptr_array = g_ptr_array_new_full (self->reserved_size, NULL);
|
||||
|
||||
/* Copy elements from stack space to GPtrArray */
|
||||
for (i = 0; i < self->len; i++)
|
||||
g_ptr_array_add (self->ptr_array, self->stack_space[i]);
|
||||
}
|
||||
|
||||
g_ptr_array_add (self->ptr_array, element);
|
||||
self->len++; /* We still count self->len */
|
||||
}
|
||||
|
||||
static inline void
|
||||
gtk_array_free (GtkArray *self,
|
||||
GDestroyNotify element_free_func)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (G_LIKELY (!self->ptr_array))
|
||||
{
|
||||
if (element_free_func)
|
||||
{
|
||||
for (i = 0; i < self->len; i++)
|
||||
element_free_func (self->stack_space[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (self->ptr_array);
|
||||
|
||||
if (element_free_func)
|
||||
{
|
||||
for (i = 0; i < self->ptr_array->len; i++)
|
||||
element_free_func (g_ptr_array_index (self->ptr_array, i));
|
||||
}
|
||||
|
||||
g_ptr_array_free (self->ptr_array, TRUE);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -95,6 +95,7 @@
|
||||
#include "gdk/gdk-private.h"
|
||||
#include "gsk/gskprivate.h"
|
||||
#include "gsk/gskrendernodeprivate.h"
|
||||
#include "gtkarrayimplprivate.h"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
@ -1310,7 +1311,8 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
double x, y;
|
||||
GtkWidget *prev;
|
||||
gboolean seen_ancestor;
|
||||
GPtrArray *targets;
|
||||
GtkArray target_array;
|
||||
GtkWidget *stack_targets[16];
|
||||
int i;
|
||||
|
||||
if (old_target == new_target)
|
||||
@ -1364,19 +1366,19 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
widget = _gtk_widget_get_parent (widget);
|
||||
}
|
||||
|
||||
targets = g_ptr_array_new_full (16, NULL);
|
||||
gtk_array_init (&target_array, (void**)stack_targets, 16);
|
||||
for (widget = new_target; widget; widget = _gtk_widget_get_parent (widget))
|
||||
g_ptr_array_add (targets, widget);
|
||||
gtk_array_add (&target_array, widget);
|
||||
|
||||
crossing.direction = GTK_CROSSING_IN;
|
||||
|
||||
seen_ancestor = FALSE;
|
||||
for (i = (int)targets->len - 1; i >= 0; i--)
|
||||
for (i = (int)target_array.len - 1; i >= 0; i--)
|
||||
{
|
||||
widget = g_ptr_array_index (targets, i);
|
||||
widget = gtk_array_index (&target_array, i);
|
||||
|
||||
if (i < (int)targets->len - 1)
|
||||
crossing.new_descendent = g_ptr_array_index (targets, i + 1);
|
||||
if (i < (int)target_array.len - 1)
|
||||
crossing.new_descendent = gtk_array_index (&target_array, i + 1);
|
||||
else
|
||||
crossing.new_descendent = NULL;
|
||||
|
||||
@ -1405,7 +1407,7 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
}
|
||||
|
||||
g_ptr_array_free (targets, TRUE);
|
||||
gtk_array_free (&target_array, NULL);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
@ -2130,11 +2132,12 @@ propagate_event_down (GtkWidget *widget,
|
||||
{
|
||||
gint handled_event = FALSE;
|
||||
GtkWidget *target = widget;
|
||||
GPtrArray *widgets;
|
||||
GtkArray widget_array;
|
||||
GtkWidget *stack_widgets[16];
|
||||
int i;
|
||||
|
||||
widgets = g_ptr_array_new_full (16, g_object_unref);
|
||||
g_ptr_array_add (widgets, g_object_ref (widget));
|
||||
gtk_array_init (&widget_array, (void**)stack_widgets, 16);
|
||||
gtk_array_add (&widget_array, g_object_ref (widget));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -2142,16 +2145,16 @@ propagate_event_down (GtkWidget *widget,
|
||||
if (!widget)
|
||||
break;
|
||||
|
||||
g_ptr_array_add (widgets, g_object_ref (widget));
|
||||
gtk_array_add (&widget_array, g_object_ref (widget));
|
||||
|
||||
if (widget == topmost)
|
||||
break;
|
||||
}
|
||||
|
||||
i = (int)widgets->len - 1;
|
||||
i = widget_array.len - 1;
|
||||
for (;;)
|
||||
{
|
||||
widget = g_ptr_array_index (widgets, i);
|
||||
widget = gtk_array_index (&widget_array, i);
|
||||
|
||||
if (!_gtk_widget_is_sensitive (widget))
|
||||
{
|
||||
@ -2177,7 +2180,7 @@ propagate_event_down (GtkWidget *widget,
|
||||
i--;
|
||||
}
|
||||
|
||||
g_ptr_array_free (widgets, TRUE);
|
||||
gtk_array_free (&widget_array, g_object_unref);
|
||||
|
||||
return handled_event;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user