Trim needless comments and fix the picker width
Remove comments that only restate the code, keeping the section banners and the notes that carry a reason, a measured fact or an external contract. ButtonOptions.width claimed to be a fixed width but only set minWidth, so the Graph and Texture pickers grew with the name they showed. It is now what it promises, with a separate minWidth for the buttons that have two forms. Narrow buttons shrink their padding, otherwise a 24px icon button had 8px left for its glyph and truncate dropped it entirely. __gm.labelsDropped() guards that class: the overflow guard only saw text that was too wide, never a label truncated to nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f16801aef3
commit
4d84231b9f
115 files changed
+707
-1564
No files matched your search
@@ -4,21 +4,15 @@ import type { TextureRef } from '../core/model/texture';
|
||||
const DEFAULT_BASE = '/game-maker/data/textures';
|
||||
|
||||
/**
|
||||
* Keeps uploaded images on the GPU, keyed by their file name.
|
||||
*
|
||||
* Nothing is ever evicted, and that is safe rather than sloppy: file names are content
|
||||
* addressed, so a name cannot come to mean different bytes and a cached texture cannot go
|
||||
* stale. It also means the same picture used by a hundred sprites is uploaded once.
|
||||
*
|
||||
* A miss is not an error – it starts the load and reports "not yet", so the caller draws its
|
||||
* plain colour in the meantime and gets a redraw when the picture arrives. That is why a
|
||||
* sprite never flickers and why nothing here needs to be awaited.
|
||||
* Keeps uploaded images on the GPU, keyed by file name. Nothing is evicted: file names are
|
||||
* content addressed, so a cached texture can never go stale. A miss is not an error – it starts
|
||||
* the load and reports "not yet", so callers never await and get a redraw when the picture lands.
|
||||
*/
|
||||
export class TextureLibrary {
|
||||
private base = DEFAULT_BASE;
|
||||
private readonly loaded = new Map<string, Texture>();
|
||||
private readonly loading = new Set<string>();
|
||||
/** Files whose load failed; retried never, so one broken reference cannot spam the network. */
|
||||
/** Never retried, so one broken reference cannot spam the network. */
|
||||
private readonly failed = new Set<string>();
|
||||
private readonly listeners = new Set<() => void>();
|
||||
|
||||
@@ -28,12 +22,9 @@ export class TextureLibrary {
|
||||
}
|
||||
|
||||
/**
|
||||
* The picture if it is already in memory, otherwise null while it loads.
|
||||
*
|
||||
* Caveat of content addressing: two texture *assets* can name the same file (the same image
|
||||
* uploaded twice) while disagreeing about `smooth`. The scale mode belongs to the shared
|
||||
* source, so the last one drawn wins – deterministically, since draw order is stable. The
|
||||
* upload avoids creating that situation by reusing an existing asset for a known file.
|
||||
* The picture if it is in memory, otherwise null while it loads. The scale mode belongs to the
|
||||
* shared source, so two assets naming the same file with different `smooth` fight over it and
|
||||
* the last one drawn wins; upload avoids that by reusing the existing asset for a known file.
|
||||
*/
|
||||
get(ref: TextureRef): Texture | null {
|
||||
const texture = this.loaded.get(ref.file);
|
||||
@@ -44,16 +35,14 @@ export class TextureLibrary {
|
||||
const mode = ref.smooth ? 'linear' : 'nearest';
|
||||
if (texture.source.scaleMode !== mode) {
|
||||
texture.source.scaleMode = mode;
|
||||
// Assigning the mode alone is not enough, and the difference is invisible until a reload:
|
||||
// Pixi's `scaleMode` setter only writes mag/min/mipmapFilter and leaves the style's cached
|
||||
// `_sharedResourceId` in place – but that id is the key the GPU sampler is looked up under,
|
||||
// so the old sampler keeps being used. `update()` drops the id and announces the change.
|
||||
// Pixi's `scaleMode` setter leaves the style's cached `_sharedResourceId` stale, so the old
|
||||
// GPU sampler keeps being used until a reload; `update()` drops the id.
|
||||
texture.source.style.update();
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
/** Runs `fn` whenever a picture has arrived. Returns the unsubscribe. */
|
||||
/** Runs `fn` whenever a picture has arrived; returns the unsubscribe. */
|
||||
onChange(fn: () => void): () => void {
|
||||
this.listeners.add(fn);
|
||||
return () => this.listeners.delete(fn);
|
||||
@@ -77,8 +66,4 @@ export class TextureLibrary {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The one library. A second instance would only duplicate GPU uploads – the cache is keyed by
|
||||
* content, so there is nothing an instance could hold that another should not share.
|
||||
*/
|
||||
export const textureLibrary = new TextureLibrary();
|
||||
Reference in new issue
Block a user