Black Lives Matter - Action and Equality. ... Adafruit is open and shipping.
0

displayio and Layer already in a group
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

displayio and Layer already in a group

by kevinjwalters on Wed Jun 10, 2020 6:51 pm

I've just started using sprite sheets along similiar lines to the demonstration of TileGrid in the useful sprite sheet page in CircuitPython Display Support Using displayio guide. My suspicion that I might not be able to use each sprite in more than one displayio.Group has been confirmed, I think, this is the error:

Code: Select all | TOGGLE FULL SIZE
Adafruit CircuitPython 5.3.0 on 2020-04-29; Adafruit CLUE nRF52840 Express with nRF52840
>>>
>>> import displayio, board, adafruit_imageload
>>> display = board.DISPLAY
>>> s_bit, s_pal = adafruit_imageload.load("sprite-sheet.bmp",
...                                        bitmap=displayio.Bitmap,
...                                        palette=displayio.Palette)
>>> SPRITE_SIZE = s_bit.height
>>> num_sprites = s_bit.width // s_bit.height
>>> s_pal.make_transparent(0)
>>> sprites = []
>>> for idx in range(num_sprites):
...     sprite = displayio.TileGrid(s_bit, pixel_shader=s_pal,
...                                 width=1, height=1,
...                                 tile_width=SPRITE_SIZE,
...                                 tile_height=SPRITE_SIZE)
...     sprite[0] = idx
...     sprites.append(sprite)
...
...
...
>>> g1 = displayio.Group(max_size=1)
>>> g2 = displayio.Group(max_size=1)

>>> g1.append(sprites[0])
>>> g2.append(sprites[0])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Layer already in a group.


I don't need it to be in more than one Group at the same time but I do want to switch between different screens which I've built up with a hierarchy of Groups. That means I have to do some tidy up by removing the elements that I'm going to re-use when I switch to a new screen. Are there any recommended ways of doing this? I can't just let the Group go out of scope or del it as this won't trigger any immediate cleanup AFAIUI? Is there an easy, concise way of zapping everything under a Group immediately?

kevinjwalters
 
Posts: 662
Joined: Sun Oct 01, 2017 3:15 pm

Re: displayio and Layer already in a group

by tannewt on Thu Jun 11, 2020 1:57 pm

You cannot use a sprite in multiple groups because it's position is dictated by its coordinates and those of the parent group.

You can have multiple TileGrid refer to the same bitmap though.

Why do you want to move a sprite between groups? Seems like it should be independent of the groups since it moves between them.

Group doesn't have `clear` but you could call `pop` until the group is empty.

tannewt
 
Posts: 1716
Joined: Thu Oct 06, 2016 8:48 pm

Re: displayio and Layer already in a group

by kevinjwalters on Thu Jun 11, 2020 2:06 pm

I have a sprite in an intro screen with a few other things. Later in the code I then display a whole load of other stuff including that same sprite.

kevinjwalters
 
Posts: 662
Joined: Sun Oct 01, 2017 3:15 pm

Re: displayio and Layer already in a group

by kevinjwalters on Thu Jun 11, 2020 5:55 pm

To make that a bit clearer, you can see the intro screen in this video. It starts with intro screen featuring all three sprites, then there's a second screen with player names, then it goes into the first round of the almost-finished game where the sprites re-appear: Rock paper scissors game on Circuit Playground Bluefruit + TFT Gizmo with audio leakage via fingers (YouTube).

I actually made that to show an unexpected bit of signal leakage from A1 to AUDIO to the speaker from, believe it or not, a conductive finger. For the button presses at 00:15 my application is not making those sound effects, it's the screen data flowing over A1! Actually, I'm wrong there on the source, it's actually from SCL/A4, SDA/A5, RX/A6, TX and travelling further across my fingers than I thought.

kevinjwalters
 
Posts: 662
Joined: Sun Oct 01, 2017 3:15 pm

Re: displayio and Layer already in a group

by tannewt on Fri Jun 12, 2020 11:55 am

Thanks for the video! I think the easiest thing is to pop everything out of the title group when moving away from that screen.

tannewt
 
Posts: 1716
Joined: Thu Oct 06, 2016 8:48 pm

Re: displayio and Layer already in a group

by kevinjwalters on Fri Jun 12, 2020 1:02 pm

Thanks, I'll tidy up the code and ponder this some more over the weekend. For now, I'm using this to clean-up the previous screen:

Code: Select all | TOGGLE FULL SIZE
def emptyGroup(dio_group):
    """Recursive depth first removal of anything in a Group.
       Intended to be used to clean-up a previous screen
       which may have elements in the new screen
       as elements cannot be in two Groups at once since this
       will cause "ValueError: Layer already in a group".
       This only deletes Groups, it does not del the non-Group content."""
    if dio_group is None:
        return

    ### Go through Group in reverse order
    for idx in range(len(dio_group) - 1, -1, -1):
        ### Avoiding isinstance here as Label is a sub-class of Group!
        if (type(dio_group[idx]) == Group):
            emptyGroup(dio_group[idx])
        del dio_group[idx]
    del dio_group


Unrelated to that I've found I can cause display corruption with my conductive fingers too! See Circuit Playground Bluefruit with TFT Gizmo vs fingers - curious video artefacts for a demo.

I wondered if the high frequencies used for the transmission of data to the screen could have something to do with this and the first paper I found, IEEE transactions on bio-medical engineering: Rosell, Colominas, Riu, Pallas-Areny, Webster: Skin impedance from 1 Hz to 1 MHz (1988) , suggests this is the case.

humanskin-impedance-vs-frequency.png
IEEE transactions on bio-medical engineering: Rosell, Colominas, Riu, Pallas-Areny, Webster: Skin impedance from 1 Hz to 1 MHz (1988) Figure 4. Impedance versus frequency for all data.
humanskin-impedance-vs-frequency.png (11.09 KiB) Viewed 87 times


This is for electrodes with gel against skin but the trend is the important part. I guess EE people know this sort of thing!

kevinjwalters
 
Posts: 662
Joined: Sun Oct 01, 2017 3:15 pm

Re: displayio and Layer already in a group

by kevinjwalters on Wed Jun 24, 2020 12:31 pm

I'm just about to put the same text on the screen in three places. What's the most efficient way to do that? Is there any way to render some text to a bitmap and would that make sense?

kevinjwalters
 
Posts: 662
Joined: Sun Oct 01, 2017 3:15 pm

Re: displayio and Layer already in a group

by tannewt on Wed Jun 24, 2020 7:49 pm

kevinjwalters wrote:I'm just about to put the same text on the screen in three places. What's the most efficient way to do that? Is there any way to render some text to a bitmap and would that make sense?


Memory efficient or speed efficient? The individual glyphs will be shared in memory. The screen update will require transmitting to the display regardless.

A bitmap could save the pixel computation time but I'm not sure it's worth it.

tannewt
 
Posts: 1716
Joined: Thu Oct 06, 2016 8:48 pm

Re: displayio and Layer already in a group

by kevinjwalters on Thu Jun 25, 2020 10:21 am

Memory was what I was thinking plus getting a better understand of what's going on underneath the covers. I occasionally hit MemoryError issues at the moment although my main issue there is not being able to use WaveFile's buffer feature due to GH: adafruit/circuitpython: CircuitPython can't play / loop samples and BLE start_scan at the same time - memory corruption? #3030.

kevinjwalters
 
Posts: 662
Joined: Sun Oct 01, 2017 3:15 pm

Re: displayio and Layer already in a group

by kevinjwalters on Mon Jun 29, 2020 9:07 pm

I am also struggling a bit with swapping around elements in a group, e.g. if I have

Code: Select all | TOGGLE FULL SIZE
>>> g = displayio.Group()
>>> g.append(t1)
>>> g.append(t2)
>>> g.append(t3)
>>> g.append(t4)


And I want to swap t2 and t3 around I'm not sure of the easiest way to do this as it gives a ValueError: Layer already in a group as they are swapped. I was wondering if this was a "magic" way of doing it:

Code: Select all | TOGGLE FULL SIZE
>>> g[1], g[2] = g[2], g[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Layer already in a group.


Apparently not!

kevinjwalters
 
Posts: 662
Joined: Sun Oct 01, 2017 3:15 pm

Re: displayio and Layer already in a group

by tannewt on Tue Jun 30, 2020 12:38 pm

`g[2]` reads the value but leaves it in the group. You can do `pop()` on the right hand side. But beware that the comma may create an intermediate tuple.

tannewt
 
Posts: 1716
Joined: Thu Oct 06, 2016 8:48 pm

Please be positive and constructive with your questions and comments.