Compare commits
3 Commits
d5275e5e28
...
3f440728fc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f440728fc
|
||
|
|
da09f8ba1e
|
||
|
|
ddc3b4ce35
|
@@ -3,6 +3,7 @@ import { getContext, setContext } from 'svelte';
|
||||
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
|
||||
import type { OrthographicCamera, Vector3 } from 'three';
|
||||
import type { GraphManager } from './graph-manager.svelte';
|
||||
import { getNodeHeight, getSocketPosition } from './helpers/nodeHelpers';
|
||||
|
||||
const graphStateKey = Symbol('graph-state');
|
||||
export function getGraphState() {
|
||||
@@ -159,56 +160,6 @@ export class GraphState {
|
||||
return 1;
|
||||
}
|
||||
|
||||
getSocketPosition(
|
||||
node: NodeInstance,
|
||||
index: string | number
|
||||
): [number, number] {
|
||||
if (typeof index === 'number') {
|
||||
return [
|
||||
(node?.state?.x ?? node.position[0]) + 20,
|
||||
(node?.state?.y ?? node.position[1]) + 2.5 + 10 * index
|
||||
];
|
||||
} else {
|
||||
const _index = Object.keys(node.state?.type?.inputs || {}).indexOf(index);
|
||||
return [
|
||||
node?.state?.x ?? node.position[0],
|
||||
(node?.state?.y ?? node.position[1]) + 10 + 10 * _index
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private nodeHeightCache: Record<string, number> = {};
|
||||
getNodeHeight(nodeTypeId: string) {
|
||||
if (nodeTypeId in this.nodeHeightCache) {
|
||||
return this.nodeHeightCache[nodeTypeId];
|
||||
}
|
||||
const node = this.graph.getNodeType(nodeTypeId);
|
||||
if (!node?.inputs) {
|
||||
return 5;
|
||||
}
|
||||
let height = 5;
|
||||
|
||||
for (const key of Object.keys(node.inputs)) {
|
||||
if (key === 'seed') continue;
|
||||
if (!node.inputs) continue;
|
||||
if (node?.inputs?.[key] === undefined) continue;
|
||||
if ('setting' in node.inputs[key]) continue;
|
||||
if (node.inputs[key].hidden) continue;
|
||||
if (
|
||||
node.inputs[key].type === 'shape'
|
||||
&& node.inputs[key].external !== true
|
||||
&& node.inputs[key].internal !== false
|
||||
) {
|
||||
height += 20;
|
||||
continue;
|
||||
}
|
||||
height += 10;
|
||||
}
|
||||
|
||||
this.nodeHeightCache[nodeTypeId] = height;
|
||||
return height;
|
||||
}
|
||||
|
||||
copyNodes() {
|
||||
if (this.activeNodeId === -1 && !this.selectedNodes?.size) {
|
||||
return;
|
||||
@@ -266,7 +217,7 @@ export class GraphState {
|
||||
if (edge[3] === index) {
|
||||
node = edge[0];
|
||||
index = edge[1];
|
||||
position = this.getSocketPosition(node, index);
|
||||
position = getSocketPosition(node, index);
|
||||
this.graph.removeEdge(edge);
|
||||
break;
|
||||
}
|
||||
@@ -286,7 +237,7 @@ export class GraphState {
|
||||
return {
|
||||
node,
|
||||
index,
|
||||
position: this.getSocketPosition(node, index)
|
||||
position: getSocketPosition(node, index)
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -323,7 +274,7 @@ export class GraphState {
|
||||
for (const node of this.graph.nodes.values()) {
|
||||
const x = node.position[0];
|
||||
const y = node.position[1];
|
||||
const height = this.getNodeHeight(node.type);
|
||||
const height = getNodeHeight(node.state.type!);
|
||||
if (downX > x && downX < x + 20 && downY > y && downY < y + height) {
|
||||
clickedNodeId = node.id;
|
||||
break;
|
||||
@@ -335,14 +286,12 @@ export class GraphState {
|
||||
}
|
||||
|
||||
isNodeInView(node: NodeInstance) {
|
||||
const height = this.getNodeHeight(node.type);
|
||||
const height = getNodeHeight(node.state.type!);
|
||||
const width = 20;
|
||||
return (
|
||||
node.position[0] > this.cameraBounds[0] - width
|
||||
return node.position[0] > this.cameraBounds[0] - width
|
||||
&& node.position[0] < this.cameraBounds[1]
|
||||
&& node.position[1] > this.cameraBounds[2] - height
|
||||
&& node.position[1] < this.cameraBounds[3]
|
||||
);
|
||||
&& node.position[1] < this.cameraBounds[3];
|
||||
}
|
||||
|
||||
openNodePalette() {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
import Debug from '../debug/Debug.svelte';
|
||||
import EdgeEl from '../edges/Edge.svelte';
|
||||
import { getGraphManager, getGraphState } from '../graph-state.svelte';
|
||||
import { getSocketPosition } from '../helpers/nodeHelpers';
|
||||
import NodeEl from '../node/Node.svelte';
|
||||
import { maxZoom, minZoom } from './constants';
|
||||
import { FileDropEventManager } from './drop.events';
|
||||
@@ -38,8 +39,8 @@
|
||||
return [0, 0, 0, 0];
|
||||
}
|
||||
|
||||
const pos1 = graphState.getSocketPosition(fromNode, edge[1]);
|
||||
const pos2 = graphState.getSocketPosition(toNode, edge[3]);
|
||||
const pos1 = getSocketPosition(fromNode, edge[1]);
|
||||
const pos2 = getSocketPosition(toNode, edge[3]);
|
||||
return [pos1[0], pos1[1], pos2[0], pos2[1]];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { type NodeInstance } from '@nodarium/types';
|
||||
import type { GraphManager } from '../graph-manager.svelte';
|
||||
import { type GraphState } from '../graph-state.svelte';
|
||||
import { snapToGrid as snapPointToGrid } from '../helpers';
|
||||
import { getNodeHeight } from '../helpers/nodeHelpers';
|
||||
import { maxZoom, minZoom, zoomSpeed } from './constants';
|
||||
import { EdgeInteractionManager } from './edge.events';
|
||||
|
||||
@@ -289,7 +290,7 @@ export class MouseEventManager {
|
||||
if (!node?.state) continue;
|
||||
const x = node.position[0];
|
||||
const y = node.position[1];
|
||||
const height = this.state.getNodeHeight(node.type);
|
||||
const height = getNodeHeight(node.state.type!);
|
||||
if (x > x1 - 20 && x < x2 && y > y1 - height && y < y2) {
|
||||
this.state.selectedNodes?.add(node.id);
|
||||
} else {
|
||||
|
||||
@@ -35,6 +35,9 @@ export function createNodePath({
|
||||
rightBump = false,
|
||||
aspectRatio = 1
|
||||
} = {}) {
|
||||
const leftBumpTopY = y + height / 2;
|
||||
const leftBumpBottomY = y - height / 2;
|
||||
|
||||
return `M0,${cornerTop}
|
||||
${
|
||||
cornerTop
|
||||
@@ -64,9 +67,7 @@ export function createNodePath({
|
||||
}
|
||||
${
|
||||
leftBump
|
||||
? ` V${y + height / 2} C${depth},${y + height / 2} ${depth},${y - height / 2} 0,${
|
||||
y - height / 2
|
||||
}`
|
||||
? ` V${leftBumpTopY} C${depth},${leftBumpTopY} ${depth},${leftBumpBottomY} 0,${leftBumpBottomY}`
|
||||
: ` H0`
|
||||
}
|
||||
Z`.replace(/\s+/g, ' ');
|
||||
|
||||
71
app/src/lib/graph-interface/helpers/nodeHelpers.ts
Normal file
71
app/src/lib/graph-interface/helpers/nodeHelpers.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import type { NodeDefinition, NodeInstance } from '@nodarium/types';
|
||||
|
||||
export function getParameterHeight(node: NodeDefinition, inputKey: string) {
|
||||
const input = node.inputs?.[inputKey];
|
||||
if (!input) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inputKey === 'seed') return 0;
|
||||
if (!node.inputs) return 0;
|
||||
if ('setting' in input) return 0;
|
||||
if (input.hidden) return 0;
|
||||
|
||||
if (input.type === 'shape' && input.external !== true) {
|
||||
return 200;
|
||||
}
|
||||
if (
|
||||
input?.label !== '' && !input.external && input.type !== 'path'
|
||||
&& input.type !== 'geometry'
|
||||
) {
|
||||
return 100;
|
||||
}
|
||||
return 50;
|
||||
}
|
||||
|
||||
export function getSocketPosition(
|
||||
node: NodeInstance,
|
||||
index: string | number
|
||||
): [number, number] {
|
||||
if (typeof index === 'number') {
|
||||
return [
|
||||
(node?.state?.x ?? node.position[0]) + 20,
|
||||
(node?.state?.y ?? node.position[1]) + 2.5 + 10 * index
|
||||
];
|
||||
} else {
|
||||
let height = 5;
|
||||
let nodeType = node.state.type!;
|
||||
const inputs = nodeType.inputs || {};
|
||||
for (const inputKey in inputs) {
|
||||
const h = getParameterHeight(nodeType, inputKey) / 10;
|
||||
if (inputKey === index) {
|
||||
height += h / 2;
|
||||
break;
|
||||
}
|
||||
height += h;
|
||||
}
|
||||
return [
|
||||
node?.state?.x ?? node.position[0],
|
||||
(node?.state?.y ?? node.position[1]) + height
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
const nodeHeightCache: Record<string, number> = {};
|
||||
export function getNodeHeight(node: NodeDefinition) {
|
||||
if (node.id in nodeHeightCache) {
|
||||
return nodeHeightCache[node.id];
|
||||
}
|
||||
if (!node?.inputs) {
|
||||
return 5;
|
||||
}
|
||||
let height = 5;
|
||||
|
||||
for (const key in node.inputs) {
|
||||
const h = getParameterHeight(node, key) / 10;
|
||||
height += h;
|
||||
}
|
||||
|
||||
nodeHeightCache[node.id] = height;
|
||||
return height;
|
||||
}
|
||||
@@ -1,56 +1,88 @@
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
uniform float uWidth;
|
||||
uniform float uHeight;
|
||||
uniform float uZoom;
|
||||
|
||||
uniform vec3 uColorDark;
|
||||
uniform vec3 uColorBright;
|
||||
|
||||
uniform vec3 uStrokeColor;
|
||||
uniform float uStrokeWidth;
|
||||
|
||||
const float uHeaderHeight = 5.0;
|
||||
uniform float uSectionHeights[16];
|
||||
uniform int uNumSections;
|
||||
|
||||
float msign(in float x) { return (x < 0.0) ? -1.0 : 1.0; }
|
||||
float sdCircle(vec2 p, float r) { return length(p) - r; }
|
||||
|
||||
vec4 roundedBoxSDF( in vec2 p, in vec2 b, in float r, in float s) {
|
||||
vec2 q = abs(p) - b + r;
|
||||
float l = b.x + b.y + 1.570796 * r;
|
||||
|
||||
float k1 = min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
|
||||
float k2 = ((q.x > 0.0) ? atan(q.y, q.x) : 1.570796);
|
||||
float k3 = 3.0 + 2.0 * msign(min(p.x, -p.y)) - msign(p.x);
|
||||
float k4 = msign(p.x * p.y);
|
||||
float k5 = r * k2 + max(-q.x, 0.0);
|
||||
|
||||
float ra = s * round(k1 / s);
|
||||
float l2 = l + 1.570796 * ra;
|
||||
|
||||
return vec4(k1 - ra, k3 * l2 + k4 * (b.y + ((q.y > 0.0) ? k5 + k2 * ra : q.y)), 4.0 * l2, k1);
|
||||
}
|
||||
|
||||
void main(){
|
||||
float strokeWidth = mix(2.0, 0.5, uZoom);
|
||||
|
||||
float borderRadius = 0.5;
|
||||
float dentRadius = 0.8;
|
||||
|
||||
float y = (1.0-vUv.y) * uHeight;
|
||||
float y = (1.0 - vUv.y) * uHeight;
|
||||
float x = vUv.x * uWidth;
|
||||
|
||||
vec2 size = vec2(uWidth, uHeight);
|
||||
vec2 uv = (vUv - 0.5) * 2.0;
|
||||
vec2 uvCenter = (vUv - 0.5) * 2.0;
|
||||
|
||||
float u_border_radius = 0.4;
|
||||
vec4 distance = roundedBoxSDF(uv * size, size, u_border_radius*2.0, 0.0);
|
||||
vec4 boxData = roundedBoxSDF(uvCenter * size, size, borderRadius * 2.0, 0.0);
|
||||
float sceneSDF = boxData.w;
|
||||
|
||||
if (distance.w > 0.0 ) {
|
||||
// outside
|
||||
gl_FragColor = vec4(0.0,0.0,0.0, 0.0);
|
||||
}else{
|
||||
if (distance.w > -uStrokeWidth || mod(y+5.0, 10.0) < uStrokeWidth/2.0) {
|
||||
// draw the outer stroke
|
||||
gl_FragColor = vec4(uStrokeColor, 1.0);
|
||||
}else if (y<5.0){
|
||||
// draw the header
|
||||
gl_FragColor = vec4(uColorBright, 1.0);
|
||||
}else{
|
||||
gl_FragColor = vec4(uColorDark, 1.0);
|
||||
}
|
||||
vec2 headerDentPos = vec2(uWidth, uHeaderHeight * 0.5);
|
||||
float headerDentDist = sdCircle(vec2(x, y) - headerDentPos, dentRadius);
|
||||
sceneSDF = max(sceneSDF, -headerDentDist*2.0);
|
||||
|
||||
float currentYBoundary = uHeaderHeight;
|
||||
float previousYBoundary = uHeaderHeight;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (i >= uNumSections) break;
|
||||
|
||||
float sectionHeight = uSectionHeights[i];
|
||||
currentYBoundary += sectionHeight;
|
||||
|
||||
float centerY = previousYBoundary + (sectionHeight * 0.5);
|
||||
vec2 circlePos = vec2(0.0, centerY);
|
||||
float circleDist = sdCircle(vec2(x, y) - circlePos, dentRadius);
|
||||
|
||||
sceneSDF = max(sceneSDF, -circleDist*2.0);
|
||||
previousYBoundary = currentYBoundary;
|
||||
}
|
||||
|
||||
if (sceneSDF > 0.05) {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 finalColor = (y < uHeaderHeight) ? uColorBright : uColorDark;
|
||||
bool isDivider = false;
|
||||
|
||||
float dividerY = uHeaderHeight;
|
||||
if (abs(y - dividerY) < strokeWidth * 0.25) isDivider = true;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (i >= uNumSections - 1) break;
|
||||
dividerY += uSectionHeights[i];
|
||||
if (abs(y - dividerY) < strokeWidth * 0.25) isDivider = true;
|
||||
}
|
||||
|
||||
if (sceneSDF > -strokeWidth || isDivider) {
|
||||
gl_FragColor = vec4(uStrokeColor, 1.0);
|
||||
} else {
|
||||
gl_FragColor = vec4(finalColor, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import { type Mesh } from 'three';
|
||||
import { getGraphState } from '../graph-state.svelte';
|
||||
import { colors } from '../graph/colors.svelte';
|
||||
import { getNodeHeight, getParameterHeight } from '../helpers/nodeHelpers';
|
||||
import NodeFrag from './Node.frag';
|
||||
import NodeVert from './Node.vert';
|
||||
import NodeHtml from './NodeHTML.svelte';
|
||||
@@ -14,9 +15,10 @@
|
||||
type Props = {
|
||||
node: NodeInstance;
|
||||
inView: boolean;
|
||||
z: number;
|
||||
};
|
||||
let { node = $bindable(), inView, z }: Props = $props();
|
||||
let { node = $bindable(), inView }: Props = $props();
|
||||
|
||||
const nodeType = $derived(node.state.type!);
|
||||
|
||||
const isActive = $derived(graphState.activeNodeId === node.id);
|
||||
const isSelected = $derived(graphState.selectedNodes.has(node.id));
|
||||
@@ -29,9 +31,18 @@
|
||||
: colors.outline)
|
||||
);
|
||||
|
||||
const sectionHeights = $derived(
|
||||
Object
|
||||
.keys(nodeType.inputs || {})
|
||||
.map(key => getParameterHeight(nodeType, key) / 10)
|
||||
.filter(b => !!b)
|
||||
);
|
||||
|
||||
let meshRef: Mesh | undefined = $state();
|
||||
|
||||
const height = graphState.getNodeHeight(node.type);
|
||||
const height = getNodeHeight(node.state.type!);
|
||||
|
||||
const zoom = $derived(graphState.cameraPosition[2]);
|
||||
|
||||
$effect(() => {
|
||||
if (meshRef && !node.state?.mesh) {
|
||||
@@ -39,6 +50,10 @@
|
||||
graphState.updateNodePosition(node);
|
||||
}
|
||||
});
|
||||
const zoomValue = $derived(
|
||||
(Math.log(graphState.cameraPosition[2]) - Math.log(1)) / (Math.log(40) - Math.log(1))
|
||||
);
|
||||
// const zoomValue = (graphState.cameraPosition[2] - 1) / 39;
|
||||
</script>
|
||||
|
||||
<T.Mesh
|
||||
@@ -47,7 +62,7 @@
|
||||
position.y={0.8}
|
||||
rotation.x={-Math.PI / 2}
|
||||
bind:ref={meshRef}
|
||||
visible={inView && z < 7}
|
||||
visible={inView && zoom < 7}
|
||||
>
|
||||
<T.PlaneGeometry args={[20, height]} radius={1} />
|
||||
<T.ShaderMaterial
|
||||
@@ -57,14 +72,19 @@
|
||||
uniforms={{
|
||||
uColorBright: { value: colors['layer-2'] },
|
||||
uColorDark: { value: colors['layer-1'] },
|
||||
uStrokeColor: { value: colors['layer-2'].clone() },
|
||||
uStrokeWidth: { value: 1.0 },
|
||||
uStrokeColor: { value: colors.outline.clone() },
|
||||
uSectionHeights: { value: [5, 10] },
|
||||
uNumSections: { value: 2 },
|
||||
uWidth: { value: 20 },
|
||||
uHeight: { value: height }
|
||||
uHeight: { value: 200 },
|
||||
uZoom: { value: 1.0 }
|
||||
}}
|
||||
uniforms.uStrokeColor.value={strokeColor.clone()}
|
||||
uniforms.uStrokeWidth.value={(7 - z) / 3}
|
||||
uniforms.uZoom.value={zoomValue}
|
||||
uniforms.uHeight.value={height}
|
||||
uniforms.uSectionHeights.value={sectionHeights}
|
||||
uniforms.uNumSections.value={sectionHeights.length}
|
||||
uniforms.uStrokeColor.value={strokeColor}
|
||||
/>
|
||||
</T.Mesh>
|
||||
|
||||
<NodeHtml bind:node {inView} {isActive} {isSelected} {z} />
|
||||
<NodeHtml bind:node {inView} {isActive} {isSelected} z={zoom} />
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { appSettings } from '$lib/settings/app-settings.svelte';
|
||||
import type { NodeInstance } from '@nodarium/types';
|
||||
import { getGraphState } from '../graph-state.svelte';
|
||||
import { createNodePath } from '../helpers/index.js';
|
||||
import { getSocketPosition } from '../helpers/nodeHelpers';
|
||||
|
||||
const graphState = getGraphState();
|
||||
|
||||
@@ -14,7 +16,7 @@
|
||||
graphState.setDownSocket?.({
|
||||
node,
|
||||
index: 0,
|
||||
position: graphState.getSocketPosition?.(node, 0)
|
||||
position: getSocketPosition?.(node, 0)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -47,6 +49,9 @@
|
||||
|
||||
<div class="wrapper" data-node-id={node.id} data-node-type={node.type}>
|
||||
<div class="content">
|
||||
{#if appSettings.value.debug.advancedMode}
|
||||
<span class="bg-white text-black! mr-2 px-1 rounded-sm opacity-30">{node.id}</span>
|
||||
{/if}
|
||||
{node.type.split('/').pop()}
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import type { NodeInput, NodeInstance } from '@nodarium/types';
|
||||
import { getGraphManager, getGraphState } from '../graph-state.svelte';
|
||||
import { createNodePath } from '../helpers';
|
||||
import { getParameterHeight, getSocketPosition } from '../helpers/nodeHelpers';
|
||||
import NodeInputEl from './NodeInput.svelte';
|
||||
|
||||
type Props = {
|
||||
@@ -12,19 +13,18 @@
|
||||
};
|
||||
|
||||
const graph = getGraphManager();
|
||||
const graphState = getGraphState();
|
||||
const graphId = graph?.id;
|
||||
const elementId = `input-${Math.random().toString(36).substring(7)}`;
|
||||
|
||||
let { node = $bindable(), input, id, isLast }: Props = $props();
|
||||
|
||||
const inputType = $derived(node?.state?.type?.inputs?.[id]);
|
||||
const nodeType = $derived(node.state.type!);
|
||||
|
||||
const inputType = $derived(nodeType.inputs?.[id]);
|
||||
|
||||
const socketId = $derived(`${node.id}-${id}`);
|
||||
const isShape = $derived(input.type === 'shape' && input.external !== true);
|
||||
const height = $derived(isShape ? 200 : 100);
|
||||
|
||||
const graphState = getGraphState();
|
||||
const graphId = graph?.id;
|
||||
|
||||
const elementId = `input-${Math.random().toString(36).substring(7)}`;
|
||||
const height = $derived(getParameterHeight(nodeType, id));
|
||||
|
||||
function handleMouseDown(ev: MouseEvent) {
|
||||
ev.preventDefault();
|
||||
@@ -32,18 +32,18 @@
|
||||
graphState.setDownSocket({
|
||||
node,
|
||||
index: id,
|
||||
position: graphState.getSocketPosition?.(node, id)
|
||||
position: getSocketPosition(node, id)
|
||||
});
|
||||
}
|
||||
|
||||
const leftBump = $derived(node.state?.type?.inputs?.[id].internal !== true);
|
||||
const leftBump = $derived(nodeType.inputs?.[id].internal !== true);
|
||||
const cornerBottom = $derived(isLast ? 5 : 0);
|
||||
const aspectRatio = 0.5;
|
||||
|
||||
const path = $derived(
|
||||
createNodePath({
|
||||
depth: 6,
|
||||
height: 18,
|
||||
height: 2000 / height,
|
||||
y: 50.5,
|
||||
cornerBottom,
|
||||
leftBump,
|
||||
@@ -53,7 +53,7 @@
|
||||
const pathHover = $derived(
|
||||
createNodePath({
|
||||
depth: 7,
|
||||
height: 20,
|
||||
height: 2200 / height,
|
||||
y: 50.5,
|
||||
cornerBottom,
|
||||
leftBump,
|
||||
@@ -74,10 +74,6 @@
|
||||
{#if inputType?.label !== ''}
|
||||
<label for={elementId} title={input.description}>{input.label || id}</label>
|
||||
{/if}
|
||||
<span
|
||||
class="absolute i-[tabler--help-circle] size-4 block top-2 right-2 opacity-30"
|
||||
title={JSON.stringify(input, null, 2)}
|
||||
></span>
|
||||
{#if inputType?.external !== true}
|
||||
<NodeInputEl {graph} {elementId} bind:node {input} {id} />
|
||||
{/if}
|
||||
|
||||
23
app/src/lib/node-registry/debugNode.ts
Normal file
23
app/src/lib/node-registry/debugNode.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
const data: Record<string, unknown> = {};
|
||||
|
||||
export function clearDebugData() {
|
||||
for (const key in data) {
|
||||
delete data[key];
|
||||
}
|
||||
}
|
||||
|
||||
export function getDebugData() {
|
||||
return { ...data };
|
||||
}
|
||||
|
||||
export const debugNode = {
|
||||
id: 'max/plantarium/debug',
|
||||
inputs: {
|
||||
a: {
|
||||
type: '*'
|
||||
}
|
||||
},
|
||||
execute(data: Int32Array) {
|
||||
return data;
|
||||
}
|
||||
} as const;
|
||||
@@ -59,6 +59,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
private definitionMap: Map<string, NodeDefinition> = new Map();
|
||||
|
||||
private seed = Math.floor(Math.random() * 100000000);
|
||||
private debugData: Record<string, Int32Array> = {};
|
||||
|
||||
perf?: PerformanceStore;
|
||||
|
||||
@@ -139,6 +140,14 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
nodes.push(node);
|
||||
}
|
||||
|
||||
for (const node of graphNodes) {
|
||||
if (node.type.endsWith('/debug')) {
|
||||
node.state = node.state || {};
|
||||
node.state.depth = Math.min(...node.state.parents.map(s => s.state.depth), 1) - 1;
|
||||
nodes.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
return [outputNode, nodes] as const;
|
||||
}
|
||||
|
||||
@@ -146,6 +155,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
this.perf?.addPoint('runtime');
|
||||
|
||||
let a = performance.now();
|
||||
this.debugData = {};
|
||||
|
||||
// Then we add some metadata to the graph
|
||||
const [outputNode, nodes] = await this.addMetaData(graph);
|
||||
@@ -245,6 +255,9 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
log.log(`Inputs:`, inputs);
|
||||
a = performance.now();
|
||||
results[node.id] = node_type.execute(encoded_inputs);
|
||||
if (node_type.id.endsWith('/debug')) {
|
||||
this.debugData[node.id] = results[node.id];
|
||||
}
|
||||
log.log('Executed', node.type, node.id);
|
||||
b = performance.now();
|
||||
|
||||
@@ -273,6 +286,10 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
return res as unknown as Int32Array;
|
||||
}
|
||||
|
||||
getDebugData() {
|
||||
return this.debugData;
|
||||
}
|
||||
|
||||
getPerformanceData() {
|
||||
return this.perf?.get();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { debugNode } from '$lib/node-registry/debugNode';
|
||||
import { IndexDBCache, RemoteNodeRegistry } from '$lib/node-registry/index';
|
||||
import type { Graph } from '@nodarium/types';
|
||||
import { createPerformanceStore } from '@nodarium/utils';
|
||||
@@ -5,7 +6,7 @@ import { MemoryRuntimeExecutor } from './runtime-executor';
|
||||
import { MemoryRuntimeCache } from './runtime-executor-cache';
|
||||
|
||||
const indexDbCache = new IndexDBCache('node-registry');
|
||||
const nodeRegistry = new RemoteNodeRegistry('', indexDbCache);
|
||||
const nodeRegistry = new RemoteNodeRegistry('', indexDbCache, [debugNode]);
|
||||
|
||||
const cache = new MemoryRuntimeCache();
|
||||
const executor = new MemoryRuntimeExecutor(nodeRegistry, cache);
|
||||
@@ -43,3 +44,7 @@ export async function executeGraph(
|
||||
export function getPerformanceData() {
|
||||
return performanceStore.get();
|
||||
}
|
||||
|
||||
export function getDebugData() {
|
||||
return executor.getDebugData();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import Grid from '$lib/grid';
|
||||
import { debounceAsyncFunction } from '$lib/helpers';
|
||||
import { createKeyMap } from '$lib/helpers/createKeyMap';
|
||||
import { debugNode } from '$lib/node-registry/debugNode.js';
|
||||
import { IndexDBCache, RemoteNodeRegistry } from '$lib/node-registry/index';
|
||||
import NodeStore from '$lib/node-store/NodeStore.svelte';
|
||||
import PerformanceViewer from '$lib/performance/PerformanceViewer.svelte';
|
||||
@@ -33,19 +34,6 @@
|
||||
|
||||
const registryCache = new IndexDBCache('node-registry');
|
||||
|
||||
const debugNode = {
|
||||
id: 'max/plantarium/debug',
|
||||
inputs: {
|
||||
a: {
|
||||
type: '*'
|
||||
}
|
||||
},
|
||||
execute(data: Int32Array) {
|
||||
console.log({ data });
|
||||
return data;
|
||||
}
|
||||
} as const;
|
||||
|
||||
const nodeRegistry = new RemoteNodeRegistry('', registryCache, [debugNode]);
|
||||
const workerRuntime = new WorkerRuntimeExecutor();
|
||||
const runtimeCache = new MemoryRuntimeCache();
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
prefix: "i";
|
||||
}
|
||||
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}layer-0");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}layer-1");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}layer-2");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}layer-3");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}layer-0{/30,/50,}");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}layer-1{/30,/50,}");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}layer-2{/30,/50,}");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}layer-3{/30,/50,}");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}active");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}selected");
|
||||
@source inline("{hover:,}{bg-,outline-,text-,}outline{!,}");
|
||||
|
||||
Reference in New Issue
Block a user