diff options
| author | Scott Shawcroft <scott@adafruit.com> | 2021-03-02 09:59:58 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-02 09:59:58 -0800 |
| commit | e4f0e47d9f0bb620f56b93c649197b16105ab5b2 (patch) | |
| tree | 2a3b9b292039ba592866690f8f89d6f61e288123 /shared-module | |
| parent | ce70b95990b45b4799055b6b7e7d347ac35257a0 (diff) | |
| parent | cb2cf81136c48695b1097fb2f601bce90e1086c9 (diff) | |
Merge pull request #4233 from pewpew-game/displayio-group-list
displayio: make Group use a python list internally
Diffstat (limited to 'shared-module')
| -rw-r--r-- | shared-module/displayio/Group.c | 235 | ||||
| -rw-r--r-- | shared-module/displayio/Group.h | 12 |
2 files changed, 139 insertions, 108 deletions
diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 15cf5b8e4..42efeb18c 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -27,6 +27,7 @@ #include "shared-bindings/displayio/Group.h" #include "py/runtime.h" +#include "py/objlist.h" #include "shared-bindings/displayio/TileGrid.h" #if CIRCUITPY_VECTORIO @@ -34,9 +35,9 @@ #endif -void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) { - displayio_group_child_t* children = m_new(displayio_group_child_t, max_size); - displayio_group_construct(self, children, max_size, scale, x, y); +void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t scale, mp_int_t x, mp_int_t y) { + mp_obj_list_t *members = mp_obj_new_list(0, NULL); + displayio_group_construct(self, members, scale, x, y); } bool common_hal_displayio_group_get_hidden(displayio_group_t* self) { @@ -51,12 +52,19 @@ void common_hal_displayio_group_set_hidden(displayio_group_t* self, bool hidden) if (self->hidden_by_parent) { return; } - for (size_t i = 0; i < self->size; i++) { - mp_obj_t layer = self->children[i].native; - if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + for (size_t i = 0; i < self->members->len; i++) { + mp_obj_t layer; + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_tilegrid_type); + if (layer != MP_OBJ_NULL) { displayio_tilegrid_set_hidden_by_parent(layer, hidden); - } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + continue; + } + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_group_type); + if (layer != MP_OBJ_NULL) { displayio_group_set_hidden_by_parent(layer, hidden); + continue; } } } @@ -70,12 +78,19 @@ void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden) if (self->hidden) { return; } - for (size_t i = 0; i < self->size; i++) { - mp_obj_t layer = self->children[i].native; - if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + for (size_t i = 0; i < self->members->len; i++) { + mp_obj_t layer; + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_tilegrid_type); + if (layer != MP_OBJ_NULL) { displayio_tilegrid_set_hidden_by_parent(layer, hidden); - } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + continue; + } + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_group_type); + if (layer != MP_OBJ_NULL) { displayio_group_set_hidden_by_parent(layer, hidden); + continue; } } } @@ -86,16 +101,22 @@ uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) { bool displayio_group_get_previous_area(displayio_group_t *self, displayio_area_t* area) { bool first = true; - for (size_t i = 0; i < self->size; i++) { - mp_obj_t layer = self->children[i].native; + for (size_t i = 0; i < self->members->len; i++) { + mp_obj_t layer; displayio_area_t layer_area; - if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_tilegrid_type); + if (layer != MP_OBJ_NULL) { if (!displayio_tilegrid_get_previous_area(layer, &layer_area)) { continue; } - } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { - if (!displayio_group_get_previous_area(layer, &layer_area)) { - continue; + } else { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_group_type); + if (layer != MP_OBJ_NULL) { + if (!displayio_group_get_previous_area(layer, &layer_area)) { + continue; + } } } if (first) { @@ -120,18 +141,27 @@ static void _update_child_transforms(displayio_group_t* self) { if (!self->in_group) { return; } - for (size_t i = 0; i < self->size; i++) { - mp_obj_t layer = self->children[i].native; + for (size_t i = 0; i < self->members->len; i++) { + mp_obj_t layer; #if CIRCUITPY_VECTORIO - if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &vectorio_vector_shape_type); + if (layer != MP_OBJ_NULL) { vectorio_vector_shape_update_transform(layer, &self->absolute_transform); + continue; } - else #endif - if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_tilegrid_type); + if (layer != MP_OBJ_NULL) { displayio_tilegrid_update_transform(layer, &self->absolute_transform); - } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + continue; + } + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_group_type); + if (layer != MP_OBJ_NULL) { displayio_group_update_transform(layer, &self->absolute_transform); + continue; } } } @@ -210,21 +240,17 @@ void common_hal_displayio_group_set_y(displayio_group_t* self, mp_int_t y) { _update_child_transforms(self); } -static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) { +static void _add_layer(displayio_group_t* self, mp_obj_t layer) { mp_obj_t native_layer; #if CIRCUITPY_VECTORIO native_layer = mp_instance_cast_to_native_base(layer, &vectorio_vector_shape_type); if (native_layer != MP_OBJ_NULL) { vectorio_vector_shape_update_transform(native_layer, &self->absolute_transform); - return native_layer; + return; } #endif - native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); - if (native_layer == MP_OBJ_NULL) { - native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type); - if (native_layer == MP_OBJ_NULL) { - mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass.")); - } + native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type); + if (native_layer != MP_OBJ_NULL) { displayio_tilegrid_t* tilegrid = native_layer; if (tilegrid->in_group) { mp_raise_ValueError(translate("Layer already in a group.")); @@ -232,7 +258,10 @@ static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) { tilegrid->in_group = true; } displayio_tilegrid_update_transform(tilegrid, &self->absolute_transform); - } else { + return; + } + native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); + if (native_layer != MP_OBJ_NULL) { displayio_group_t* group = native_layer; if (group->in_group) { mp_raise_ValueError(translate("Layer already in a group.")); @@ -240,27 +269,34 @@ static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) { group->in_group = true; } displayio_group_update_transform(group, &self->absolute_transform); + return; } - return native_layer; + mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass.")); } static void _remove_layer(displayio_group_t* self, size_t index) { - mp_obj_t layer = self->children[index].native; + mp_obj_t layer; displayio_area_t layer_area; bool rendered_last_frame = false; #if CIRCUITPY_VECTORIO - if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[index], &vectorio_vector_shape_type); + if (layer != MP_OBJ_NULL) { bool has_dirty_area = vectorio_vector_shape_get_dirty_area(layer, &layer_area); rendered_last_frame = has_dirty_area; vectorio_vector_shape_update_transform(layer, NULL); } - else #endif - if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[index], &displayio_tilegrid_type); + if (layer != MP_OBJ_NULL) { displayio_tilegrid_t* tilegrid = layer; rendered_last_frame = displayio_tilegrid_get_previous_area(tilegrid, &layer_area); displayio_tilegrid_update_transform(tilegrid, NULL); - } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + } + layer = mp_instance_cast_to_native_base( + self->members->items[index], &displayio_group_type); + if (layer != MP_OBJ_NULL) { displayio_group_t* group = layer; rendered_last_frame = displayio_group_get_previous_area(group, &layer_area); displayio_group_update_transform(group, NULL); @@ -277,62 +313,40 @@ static void _remove_layer(displayio_group_t* self, size_t index) { } void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer) { - if (self->size == self->max_size) { - mp_raise_RuntimeError(translate("Group full")); - } - mp_obj_t native_layer = _add_layer(self, layer); - // Shift everything right. - for (size_t i = self->size; i > index; i--) { - self->children[i] = self->children[i - 1]; - } - self->children[index].native = native_layer; - self->children[index].original = layer; - self->size++; + _add_layer(self, layer); + mp_obj_list_insert(self->members, index, layer); } mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index) { - self->size--; - mp_obj_t item = self->children[index].original; _remove_layer(self, index); - - // Shift everything left. - for (size_t i = index; i < self->size; i++) { - self->children[i] = self->children[i + 1]; - } - self->children[self->size].native = NULL; - self->children[self->size].original = NULL; - return item; + return mp_obj_list_pop(self->members, index); } mp_int_t common_hal_displayio_group_index(displayio_group_t* self, mp_obj_t layer) { - for (size_t i = 0; i < self->size; i++) { - if (self->children[i].original == layer) { - return i; - } - } - return -1; + mp_obj_t args[] = {self->members, layer}; + mp_obj_t *index = mp_seq_index_obj( + self->members->items, self->members->len, 2, args); + return MP_OBJ_SMALL_INT_VALUE(index); } size_t common_hal_displayio_group_get_len(displayio_group_t* self) { - return self->size; + return self->members->len; } mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index) { - return self->children[index].original; + return self->members->items[index]; } void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer) { - mp_obj_t native_layer = _add_layer(self, layer); + _add_layer(self, layer); _remove_layer(self, index); - self->children[index].native = native_layer; - self->children[index].original = layer; + mp_obj_list_store(self, MP_OBJ_NEW_SMALL_INT(index), layer); } -void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) { +void displayio_group_construct(displayio_group_t* self, mp_obj_list_t* members, uint32_t scale, mp_int_t x, mp_int_t y) { self->x = x; self->y = y; - self->children = child_array; - self->max_size = max_size; + self->members = members; self->item_removed = false; self->scale = scale; self->in_group = false; @@ -341,47 +355,61 @@ void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t* buffer) { // Track if any of the layers finishes filling in the given area. We can ignore any remaining // layers at that point. - bool full_coverage = false; - for (int32_t i = self->size - 1; i >= 0 ; i--) { - mp_obj_t layer = self->children[i].native; + for (int32_t i = self->members->len - 1; i >= 0 ; i--) { + mp_obj_t layer; #if CIRCUITPY_VECTORIO - if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &vectorio_vector_shape_type); + if (layer != MP_OBJ_NULL) { if (vectorio_vector_shape_fill_area(layer, colorspace, area, mask, buffer)) { - full_coverage = true; - break; + return true; } + continue; } - else #endif - if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_tilegrid_type); + if (layer != MP_OBJ_NULL) { if (displayio_tilegrid_fill_area(layer, colorspace, area, mask, buffer)) { - full_coverage = true; - break; + return true; } - } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + continue; + } + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_group_type); + if (layer != MP_OBJ_NULL) { if (displayio_group_fill_area(layer, colorspace, area, mask, buffer)) { - full_coverage = true; - break; + return true; } + continue; } } - return full_coverage; + return false; } void displayio_group_finish_refresh(displayio_group_t *self) { self->item_removed = false; - for (int32_t i = self->size - 1; i >= 0 ; i--) { - mp_obj_t layer = self->children[i].native; + for (int32_t i = self->members->len - 1; i >= 0 ; i--) { + mp_obj_t layer; #if CIRCUITPY_VECTORIO - if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &vectorio_vector_shape_type); + if (layer != MP_OBJ_NULL) { vectorio_vector_shape_finish_refresh(layer); + continue; } - else #endif - if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_tilegrid_type); + if (layer != MP_OBJ_NULL) { displayio_tilegrid_finish_refresh(layer); - } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + continue; + } + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_group_type); + if (layer != MP_OBJ_NULL) { displayio_group_finish_refresh(layer); + continue; } } } @@ -392,18 +420,27 @@ displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, dis tail = &self->dirty_area; } - for (int32_t i = self->size - 1; i >= 0 ; i--) { - mp_obj_t layer = self->children[i].native; + for (int32_t i = self->members->len - 1; i >= 0 ; i--) { + mp_obj_t layer; #if CIRCUITPY_VECTORIO - if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &vectorio_vector_shape_type); + if (layer != MP_OBJ_NULL) { tail = vectorio_vector_shape_get_refresh_areas(layer, tail); + continue; } - else #endif - if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_tilegrid_type); + if (layer != MP_OBJ_NULL) { tail = displayio_tilegrid_get_refresh_areas(layer, tail); - } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + continue; + } + layer = mp_instance_cast_to_native_base( + self->members->items[i], &displayio_group_type); + if (layer != MP_OBJ_NULL) { tail = displayio_group_get_refresh_areas(layer, tail); + continue; } } diff --git a/shared-module/displayio/Group.h b/shared-module/displayio/Group.h index 5afaac1ba..0964e0a0b 100644 --- a/shared-module/displayio/Group.h +++ b/shared-module/displayio/Group.h @@ -31,24 +31,18 @@ #include <stdint.h> #include "py/obj.h" +#include "py/objlist.h" #include "shared-module/displayio/area.h" #include "shared-module/displayio/Palette.h" typedef struct { - mp_obj_t native; - mp_obj_t original; -} displayio_group_child_t; - -typedef struct { mp_obj_base_t base; - displayio_group_child_t* children; + mp_obj_list_t *members; displayio_buffer_transform_t absolute_transform; displayio_area_t dirty_area; // Catch all for changed area int16_t x; int16_t y; uint16_t scale; - uint16_t size; - uint16_t max_size; bool item_removed :1; bool in_group :1; bool hidden :1; @@ -56,7 +50,7 @@ typedef struct { uint8_t padding :4; } displayio_group_t; -void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y); +void displayio_group_construct(displayio_group_t* self, mp_obj_list_t* members, uint32_t scale, mp_int_t x, mp_int_t y); void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden); bool displayio_group_get_previous_area(displayio_group_t *group, displayio_area_t* area); bool displayio_group_fill_area(displayio_group_t *group, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer); |
