summaryrefslogtreecommitdiff
path: root/shared-module
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2021-03-02 09:59:58 -0800
committerGitHub <noreply@github.com>2021-03-02 09:59:58 -0800
commite4f0e47d9f0bb620f56b93c649197b16105ab5b2 (patch)
tree2a3b9b292039ba592866690f8f89d6f61e288123 /shared-module
parentce70b95990b45b4799055b6b7e7d347ac35257a0 (diff)
parentcb2cf81136c48695b1097fb2f601bce90e1086c9 (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.c235
-rw-r--r--shared-module/displayio/Group.h12
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);