-
Notifications
You must be signed in to change notification settings - Fork 1
Slight changes to the CacheClient interface #253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| import type { Cacheable, SharedPriorityCache } from '@alleninstitute/vis-core'; | ||
| import reduce from 'lodash/reduce'; | ||
| import type { WebGLSafeBasicType } from './typed-array'; | ||
| import type { ColumnRequest, Item } from './types'; | ||
|
|
||
| type Content<V extends Cacheable> = Record<string, V>; | ||
|
|
||
| export function buildScatterbrainCacheClient<V extends Cacheable>( | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nearly identical to the version that has been deleted from ./renderer.ts - this version is simply slightly more generic. |
||
| cache: SharedPriorityCache, | ||
| toCacheValue: (buffer: ArrayBuffer, type: WebGLSafeBasicType) => V, | ||
| onDataArrived: () => void, | ||
| ) { | ||
| const client = cache.registerClient<Item, Content<V>>({ | ||
| cacheKeys: (item) => { | ||
| const { dataset, node, columns } = item; | ||
| return reduce<Record<string, ColumnRequest>, Record<string, string>>( | ||
| columns, | ||
| (acc, col, key) => ({ | ||
| ...acc, | ||
| [key]: `${dataset.metadata.metadataFileEndpoint}/${node.file}/${col.name}`, | ||
| }), | ||
| {}, | ||
| ); | ||
| }, | ||
| fetch: (item) => { | ||
| const { dataset, node, columns } = item; | ||
| const attrs = dataset.metadata.pointAttributes; | ||
| const getColumnUrl = (columnName: string) => | ||
| `${dataset.metadata.metadataFileEndpoint}${columnName}/${dataset.metadata.visualizationReferenceId}/${node.file}`; | ||
| const getGeneUrl = (columnName: string) => | ||
| `${dataset.metadata.geneFileEndpoint}${columnName}/${dataset.metadata.visualizationReferenceId}/${node.file}`; | ||
| const getColumnInfo = (col: ColumnRequest) => | ||
| col.type === 'QUANTITATIVE' | ||
| ? ({ url: getGeneUrl(col.name), elements: 1, type: 'float' } as const) | ||
| : { url: getColumnUrl(col.name), elements: attrs[col.name].elements, type: attrs[col.name].type }; | ||
|
|
||
| const proms = reduce<Record<string, ColumnRequest>, Record<string, (signal: AbortSignal) => Promise<V>>>( | ||
| columns, | ||
| (getters, col, key) => { | ||
| const { url, type } = getColumnInfo(col); | ||
| return { | ||
| ...getters, | ||
| [key]: (signal) => | ||
| fetch(url, { signal }).then((b) => | ||
| b.arrayBuffer().then((buff) => toCacheValue(buff, type)), | ||
| ), | ||
| }; | ||
| }, | ||
| {}, | ||
| ); | ||
| return proms; | ||
| }, | ||
| isValue: (v, item: Item): v is Content<V> => { | ||
| for (const column of Object.keys(item.columns)) { | ||
| if (!(column in v)) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| }, | ||
| onDataArrived, | ||
| }); | ||
| return client; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,8 @@ | ||
| export { buildScatterbrainCacheClient } from './cache-client'; | ||
| export { getVisibleItems, loadDataset as loadScatterbrainDataset } from './dataset'; | ||
| export { | ||
| buildRenderFrameFn as buildScatterbrainRenderFn, | ||
| buildScatterbrainCacheClient, | ||
| setCategoricalLookupTableValues, | ||
| updateCategoricalValue, | ||
| } from './renderer'; | ||
| export * from './types'; | ||
| export { getVisibleItems, loadDataset as loadScatterbrainDataset } from './dataset'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,85 +1,20 @@ | ||
| import type { SharedPriorityCache } from '@alleninstitute/vis-core'; | ||
| import type REGL from 'regl'; | ||
| import type { ColumnRequest, ScatterbrainDataset, SlideviewScatterbrainDataset, TreeNode } from './types'; | ||
| import { Box2D, type box2D, type vec4 } from '@alleninstitute/vis-geometry'; | ||
| import { MakeTaggedBufferView } from './typed-array'; | ||
| import keys from 'lodash/keys'; | ||
| import reduce from 'lodash/reduce'; | ||
| import type REGL from 'regl'; | ||
| import { buildScatterbrainCacheClient } from './cache-client'; | ||
| import { getVisibleItems, type NodeWithBounds } from './dataset'; | ||
| import { buildScatterbrainRenderCommand, type Config, configureShader, type ShaderSettings, VBO } from './shader'; | ||
| import { MakeTaggedBufferView } from './typed-array'; | ||
| import type { ColumnRequest, ScatterbrainDataset, SlideviewScatterbrainDataset, TreeNode } from './types'; | ||
|
|
||
| export type Item = Readonly<{ | ||
| dataset: SlideviewScatterbrainDataset | ScatterbrainDataset; | ||
| node: TreeNode; | ||
| bounds: box2D; | ||
| columns: Record<string, ColumnRequest>; | ||
| }>; | ||
| type Content = Record<string, VBO>; | ||
|
|
||
| export function buildScatterbrainCacheClient( | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see cache-client.ts |
||
| allNeededColumns: readonly string[], | ||
| regl: REGL.Regl, | ||
| cache: SharedPriorityCache, | ||
| onDataArrived: () => void, | ||
| ) { | ||
| const client = cache.registerClient<Item, Content>({ | ||
| cacheKeys: (item) => { | ||
| const { dataset, node, columns } = item; | ||
| return reduce<Record<string, ColumnRequest>, Record<string, string>>( | ||
| columns, | ||
| (acc, col, key) => ({ | ||
| ...acc, | ||
| [key]: `${dataset.metadata.metadataFileEndpoint}/${node.file}/${col.name}`, | ||
| }), | ||
| {}, | ||
| ); | ||
| }, | ||
| fetch: (item) => { | ||
| const { dataset, node, columns } = item; | ||
| const attrs = dataset.metadata.pointAttributes; | ||
| const getColumnUrl = (columnName: string) => | ||
| `${dataset.metadata.metadataFileEndpoint}${columnName}/${dataset.metadata.visualizationReferenceId}/${node.file}`; | ||
| const getGeneUrl = (columnName: string) => | ||
| `${dataset.metadata.geneFileEndpoint}${columnName}/${dataset.metadata.visualizationReferenceId}/${node.file}`; | ||
| const getColumnInfo = (col: ColumnRequest) => | ||
| col.type === 'QUANTITATIVE' | ||
| ? ({ url: getGeneUrl(col.name), elements: 1, type: 'float' } as const) | ||
| : { url: getColumnUrl(col.name), elements: attrs[col.name].elements, type: attrs[col.name].type }; | ||
|
|
||
| const proms = reduce<Record<string, ColumnRequest>, Record<string, (signal: AbortSignal) => Promise<VBO>>>( | ||
| columns, | ||
| (getters, col, key) => { | ||
| const { url, type } = getColumnInfo(col); | ||
| return { | ||
| ...getters, | ||
| [key]: (signal) => | ||
| fetch(url, { signal }).then((b) => | ||
| b.arrayBuffer().then((buff) => { | ||
| const typed = MakeTaggedBufferView(type, buff); | ||
| return new VBO({ | ||
| buffer: regl.buffer({ type: type, data: typed.data }), | ||
| bytes: buff.byteLength, | ||
| type: 'buffer', | ||
| }); | ||
| }), | ||
| ), | ||
| }; | ||
| }, | ||
| {}, | ||
| ); | ||
| return proms; | ||
| }, | ||
| isValue: (v): v is Content => { | ||
| for (const column of allNeededColumns) { | ||
| if (!(column in v)) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| }, | ||
| onDataArrived, | ||
| }); | ||
| return client; | ||
| } | ||
|
|
||
| function columnsForItem<T extends object>( | ||
| config: Config, | ||
|
|
@@ -175,7 +110,7 @@ export function updateCategoricalValue( | |
| type ScatterbrainRenderProps = Omit<Parameters<ReturnType<typeof buildScatterbrainRenderCommand>>[0], 'item'> & { | ||
| visibilityThresholdPx: number; | ||
| dataset: ScatterbrainDataset | SlideviewScatterbrainDataset; | ||
| client: ReturnType<typeof buildScatterbrainCacheClient>; | ||
| client: ReturnType<typeof buildScatterbrainCacheClient<VBO>>; | ||
| }; | ||
| /** | ||
| * | ||
|
|
@@ -214,8 +149,18 @@ export function buildRenderFrameFn(regl: REGL.Regl, settings: ShaderSettings) { | |
| } | ||
| }; | ||
| const connectToCache = (cache: SharedPriorityCache, onDataArrived: () => void) => { | ||
| const allColumns = [...config.categoricalColumns, ...config.quantitativeColumns, config.positionColumn]; | ||
| const client = buildScatterbrainCacheClient(allColumns, regl, cache, onDataArrived); | ||
| const client = buildScatterbrainCacheClient( | ||
| cache, | ||
| (buff, type) => { | ||
| const typed = MakeTaggedBufferView(type, buff); | ||
| return new VBO({ | ||
| buffer: regl.buffer({ type: type, data: typed.data }), | ||
| bytes: buff.byteLength, | ||
| type: 'buffer', | ||
| }); | ||
| }, | ||
| onDataArrived, | ||
| ); | ||
| return client; | ||
| }; | ||
| return { render, connectToCache }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the api change - its non-breaking. All prior cache-clients that pass an isValue method that ignores the new argument are valid, will work at runtime, and will pass typechecking still.