detached ab6686c

graphics.go RawHistoryFolder

1// Package graphics provides a renderer-neutral, bounded graphics scene.
2//
3// The package stores immutable encoded asset blobs and sparse placements. A
4// scene is mutated by its owner and publishes immutable snapshots for
5// consumers. It deliberately knows nothing about terminal protocols,
6// renderers, image formats, or text state.
7package graphics
8
9import "errors"
10
11var (
12	ErrInvalidRect        = errors.New("invalid rectangle")
13	ErrInvalidAsset       = errors.New("invalid asset")
14	ErrInvalidPlacement   = errors.New("invalid placement")
15	ErrAssetNotFound      = errors.New("asset not found")
16	ErrPlacementNotFound  = errors.New("placement not found")
17	ErrAssetInUse         = errors.New("asset is still in use")
18	ErrTooManyAssets      = errors.New("asset quota exceeded")
19	ErrTooManyPlacements  = errors.New("placement quota exceeded")
20	ErrEncodedBudget      = errors.New("encoded byte budget exceeded")
21	ErrDecodedPixelBudget = errors.New("decoded pixel budget exceeded")
22	ErrGenerationOverflow = errors.New("generation overflow")
23	ErrIdentifierOverflow = errors.New("identifier overflow")
24	ErrInvalidOperation   = errors.New("invalid graphics operation")
25	ErrInvalidSceneLimits = errors.New("invalid scene limits")
26)
27
28// AssetID identifies an asset in a scene. Its representation is deliberately
29// private: IDs are only meaningful to the scene that issued them and are not
30// interchangeable with placement IDs.
31type AssetID struct{ value uint64 }
32
33// PlacementID identifies a sparse placement in a scene.
34type PlacementID struct{ value uint64 }
35
36// Valid reports whether the ID was issued by a scene.
37func (id AssetID) Valid() bool { return id.value != 0 }
38
39// Valid reports whether the ID was issued by a scene.
40func (id PlacementID) Valid() bool { return id.value != 0 }
41
42// String returns a stable diagnostic form of the opaque ID.
43func (id AssetID) String() string { return formatID('a', id.value) }
44
45// String returns a stable diagnostic form of the opaque ID.
46func (id PlacementID) String() string { return formatID('p', id.value) }
47
48func formatID(prefix byte, value uint64) string {
49	if value == 0 {
50		return "<invalid>"
51	}
52	var buf [1 + 20]byte
53	buf[0] = prefix
54	i := len(buf)
55	for value != 0 {
56		i--
57		buf[i] = byte('0' + value%10)
58		value /= 10
59	}
60	return string(buf[0:1]) + string(buf[i:])
61}
62
63// Limits bounds live scene resources. Zero-valued limits use the package
64// defaults; this keeps a zero-value configuration bounded as well.
65type Limits struct {
66	MaxAssets                uint64
67	MaxPlacements            uint64
68	MaxEncodedBytes          uint64
69	MaxDecodedPixels         uint64
70	MaxEncodedBytesPerAsset  uint64
71	MaxDecodedPixelsPerAsset uint64
72}
73
74// Config is an alternate name for Limits for callers that prefer constructor
75// configuration terminology.
76type Config = Limits
77
78// SceneConfig is a descriptive alias for Config.
79type SceneConfig = Limits
80
81// Generation is the monotonically increasing scene generation number.
82type Generation = uint64
83
84// SnapshotRef is an explicit name for an immutable snapshot reference.
85type SnapshotRef = Snapshot
86
87// AssetInput is an alternate name for an asset registration description.
88type AssetInput = AssetBlob
89
90const (
91	DefaultMaxAssets                = uint64(1024)
92	DefaultMaxPlacements            = uint64(65536)
93	DefaultMaxEncodedBytes          = uint64(64 << 20)
94	DefaultMaxDecodedPixels         = uint64(256 << 20)
95	DefaultMaxEncodedBytesPerAsset  = uint64(16 << 20)
96	DefaultMaxDecodedPixelsPerAsset = uint64(128 << 20)
97)
98
99// AssetFormat identifies the encoded pixel layout supplied by an asset.
100type AssetFormat uint8
101
102const (
103	AssetFormatUnknown AssetFormat = iota
104	AssetFormatRGB
105	AssetFormatRGBA
106	AssetFormatPNG
107)
108
109// AssetBlob is the caller-owned description of one encoded asset. AddAsset
110// copies Encoded before returning, so later caller mutations cannot alter a
111// scene or any snapshot. Format preserves the encoded pixel layout for the
112// renderer. Width and Height describe the decoded pixel extent used for
113// clipping and quota accounting. DecodedPixels, when non-zero, must equal
114// Width*Height; accounting always uses the checked product. Scene.AddAssetOwned
115// and ReplaceAssetOwned instead take ownership of Encoded without copying it.
116type AssetBlob struct {
117	Encoded       []byte
118	Format        AssetFormat
119	Width, Height int64
120	DecodedPixels uint64
121}
122
123// AssetSpec is the conventional name for an asset input description.
124type AssetSpec = AssetBlob
125
126// PlacementSpec describes one sparse placement. Source defaults to the full
127// asset. Destination is a pixel rectangle. Cells optionally records the
128// cell-space extent associated with the same placement. HasCells and HasLayer
129// preserve explicit zero values when updating an existing placement.
130type PlacementSpec struct {
131	Asset       AssetID
132	Source      PixelRect
133	Destination PixelRect
134	Cells       CellRect
135	HasCells    bool
136	Layer       int64
137	HasLayer    bool
138}
139
140// Viewport can constrain visible fragments in pixel space, cell space, or
141// both. A zero-valued rectangle means that coordinate space is not supplied.
142type Viewport struct {
143	Pixels PixelRect
144	Cells  CellRect
145}
146
147// VisibleFragment is the visible part of a placement. Source and Destination
148// are clipped together, preserving the placement's source-to-destination
149// mapping even when the destination is scaled. Cells is populated when the
150// placement and viewport carry cell geometry.
151type VisibleFragment struct {
152	PlacementID PlacementID
153	AssetID     AssetID
154	Source      PixelRect
155	Destination PixelRect
156	Cells       CellRect
157}
158
159// Fragment is a short alias for VisibleFragment.
160type Fragment = VisibleFragment
161
162// Usage reports resources held by the current scene or an immutable snapshot.
163type Usage struct {
164	Assets        uint64
165	Placements    uint64
166	EncodedBytes  uint64
167	DecodedPixels uint64
168}
169
170// OperationKind identifies one transactional scene operation.
171type OperationKind uint8
172
173const (
174	OperationAddAsset OperationKind = iota + 1
175	OperationRemoveAsset
176	OperationPlace
177	OperationUpdatePlacement
178	OperationRemovePlacement
179)
180
181// Operation is a sparse scene operation. Add-asset operations allocate an
182// opaque ID internally; use AddAsset directly when the ID is needed by the
183// caller for a subsequent placement.
184type Operation struct {
185	Kind        OperationKind
186	Blob        AssetBlob
187	Asset       AssetID
188	Placement   PlacementSpec
189	PlacementID PlacementID
190}
191
192// Operation aliases make operation construction readable without introducing
193// protocol-specific terminology.
194const (
195	AddAssetOperation        = OperationAddAsset
196	RemoveAssetOperation     = OperationRemoveAsset
197	PlaceOperation           = OperationPlace
198	UpdatePlacementOperation = OperationUpdatePlacement
199	RemovePlacementOperation = OperationRemovePlacement
200)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 13

↑↓ moveenter openesc close