🏠 back to Observable

reactive array/map mapped onto an other map

First of all, sorry for that weird title. I am still not sure what the right wording is here.

I am creating a spritesheet-loader for pixi.js projects which yields a Map of textures as the textures are loading.


Later I want to use these textures to create sprites (which have to be added to an pixi.js container). Every time the texture map gets larger (more textures loaded) the sprites map cell (which creates a map based on the map of the textures) is beeing re-run.
This creates some overhead, since sprites will be created which are already created before and beeing destroyed via the invalidation promise (and are removed from the pixi.js container).
I only want to create sprites which are new. For that I tried to create a mutable spriteCache and was looking for a difference between the cache and the actual new texture map. But this feels odd.
The whole thing is kinda like d3-selection, but instead of the DOM I want to use the pixi.js container model.

hi @cpietsch, here is one quick idea
You could yield both Textures and Sprites from the same cell. Luckily when you have the Texture you can generate a Sprite.

In my example texturesSprites only append to stage when loadTexture and Sprites are ready. Thus, you only update Pixi.js container with new Sprites. If you rerun the cell the invalidation pattern will destroy and clean Pixi.js container.

I’d be curious to see an asynchronous generator pattern with independent cells for Textures and Sprites without getting the same issue of regenerating all the Sprites for every new group of Textures

hey @radames, thanks for your suggestion.
The reason for the seperation of the sprite and texture creation was to have this textureloader notebook as a module I could import somewhere else. True, the easy way here is to just include both in one cell.

I was stumbling on this problem/pattern for some time now on observable. In vue.js I would create a watcher and have the old and new value of an reactive variable.
Maybe a generator function could do the job here. It would need to listen for changes via an custom iterator? and then spit out the new elements.

Well,…

Exactly that is working:

Still it feels weird to do it this way. Maybe there is a way of accessing the iterator of a cell without wrapping it into a generator function ? Or the whole approach is wrong ?

That looks good! I also came across that pattern of manually handling the generator iterator https://observablehq.com/@observablehq/introduction-to-asynchronous-iteration

But if you want to avoid the Map and search for existing sprites, why not yield a group of Textures each iteration? Then you avoid yielding the existing textures all the time.

I’ve updated my fork with that idea

ps. this topic explains why Observable cell are not iterables Iterable protocol and observable

1 Like

Good Idea! I wanted to yield everything so you have the choice of listening to it or waiting for everything to finish. Kind of both ways.

Actually with this approach we can simply use the for await pattern. It is getting simpler now. Combining for await with yield * or a single yield per loop we get a stream of textures and all we have to do is to listen to it.

1 Like

I would like to use the last Notebook (which is a fork of a fork of the original) as the new code for @cpietsch/pixi-spritesheet-loader.
I can not unpublish the original one, and moving the changes upstream would destroy this thread for references. First I wanted to use the suggest function (pull request) and change the urls in this thread to the previous versions via the @version tag. But it turns out versions are private.
Is there a clever way of solving this problem ?

1 Like

There is a way to publish or share previous versions. See this link for details:

Also, you can fork a specific version, then enable link sharing and post the link here. After that, you can merge your changes upstream.

Note that any previously shared or published version will remain accessible through the version suffix, unless you disabled link sharing or unpublished a notebook at some point (which will make all versions inaccessible).

Lastly, if you want to create a copy without the fork relationship, you can follow the steps outlined in this link:

1 Like