From 222a52d347ecca2777696d23b9917cd4e7e92100 Mon Sep 17 00:00:00 2001 From: bymyself Date: Wed, 2 Jul 2025 04:33:17 -0700 Subject: [PATCH] [feat] Add feature flags and utility updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add useFeatureFlags composable for Vue nodes - Update coreSettings with Vue nodes feature flag - Minor typing improvements in useTransformState 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/composables/element/useTransformState.ts | 18 ++-- src/composables/useFeatureFlags.ts | 93 ++++++++++++++++++++ src/constants/coreSettings.ts | 46 ++++++++++ 3 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 src/composables/useFeatureFlags.ts diff --git a/src/composables/element/useTransformState.ts b/src/composables/element/useTransformState.ts index 59fd6787e5..3d8f3a8099 100644 --- a/src/composables/element/useTransformState.ts +++ b/src/composables/element/useTransformState.ts @@ -75,7 +75,7 @@ export const useTransformState = () => { margin: number = 0.2 // 20% margin by default ): boolean => { const screenPos = canvasToScreen({ x: nodePos[0], y: nodePos[1] }) - + // Adjust margin based on zoom level for better performance let adjustedMargin = margin if (camera.z < 0.1) { @@ -83,17 +83,17 @@ export const useTransformState = () => { } else if (camera.z > 3.0) { adjustedMargin = Math.max(margin * 0.5, 0.05) // Tighter at high zoom } - + // Skip nodes too small to be visible const nodeScreenSize = Math.max(nodeSize[0], nodeSize[1]) * camera.z if (nodeScreenSize < 4) { return false } - + // Early rejection tests for performance - const nodeRight = screenPos.x + (nodeSize[0] * camera.z) - const nodeBottom = screenPos.y + (nodeSize[1] * camera.z) - + const nodeRight = screenPos.x + nodeSize[0] * camera.z + const nodeBottom = screenPos.y + nodeSize[1] * camera.z + // Use actual viewport dimensions (already accounts for browser zoom via clientWidth/Height) const marginX = viewport.width * adjustedMargin const marginY = viewport.height * adjustedMargin @@ -101,11 +101,11 @@ export const useTransformState = () => { const expandedRight = viewport.width + marginX const expandedTop = -marginY const expandedBottom = viewport.height + marginY - + return !( - nodeRight < expandedLeft || + nodeRight < expandedLeft || screenPos.x > expandedRight || - nodeBottom < expandedTop || + nodeBottom < expandedTop || screenPos.y > expandedBottom ) } diff --git a/src/composables/useFeatureFlags.ts b/src/composables/useFeatureFlags.ts new file mode 100644 index 0000000000..3f1f293a46 --- /dev/null +++ b/src/composables/useFeatureFlags.ts @@ -0,0 +1,93 @@ +/** + * Feature flags composable for Vue node system + * Provides safe toggles for experimental features + */ +import { computed } from 'vue' + +import { useSettingStore } from '@/stores/settingStore' + +export const useFeatureFlags = () => { + const settingStore = useSettingStore() + + /** + * Enable Vue-based node rendering + * When disabled, falls back to standard LiteGraph canvas rendering + */ + const isVueNodesEnabled = computed(() => { + try { + return settingStore.get('Comfy.VueNodes.Enabled' as any) ?? true // Default to true for development + } catch { + return true // Default to true for development + } + }) + + /** + * Enable Vue widget rendering within Vue nodes + * When disabled, Vue nodes render without widgets (structure only) + */ + const isVueWidgetsEnabled = computed(() => { + try { + return settingStore.get('Comfy.VueNodes.Widgets' as any) ?? true + } catch { + return true + } + }) + + /** + * Enable viewport culling for performance + * When disabled, all Vue nodes render regardless of viewport + */ + const isViewportCullingEnabled = computed(() => { + try { + return settingStore.get('Comfy.VueNodes.ViewportCulling' as any) ?? true + } catch { + return true + } + }) + + /** + * Development mode features (debug panel, etc.) + * Automatically enabled in development builds + */ + const isDevModeEnabled = computed(() => { + try { + return ( + settingStore.get('Comfy.DevMode' as any) ?? + process.env.NODE_ENV === 'development' + ) + } catch { + return process.env.NODE_ENV === 'development' + } + }) + + /** + * Check if Vue nodes should be rendered at all + * Combines multiple conditions for safety + */ + const shouldRenderVueNodes = computed( + () => + isVueNodesEnabled.value && + // Add any other safety conditions here + true + ) + + /** + * Get culling margin setting + */ + const cullingMargin = computed(() => { + try { + return settingStore.get('Comfy.VueNodes.CullingMargin' as any) ?? 0.2 + } catch { + return 0.2 + } + }) + + return { + isVueNodesEnabled, + isVueWidgetsEnabled, + isViewportCullingEnabled, + isDevModeEnabled, + shouldRenderVueNodes, + cullingMargin + } +} diff --git a/src/constants/coreSettings.ts b/src/constants/coreSettings.ts index 295ea01fde..b6989d6ae8 100644 --- a/src/constants/coreSettings.ts +++ b/src/constants/coreSettings.ts @@ -866,5 +866,51 @@ export const CORE_SETTINGS: SettingParams[] = [ name: 'Release seen timestamp', type: 'hidden', defaultValue: 0 + }, + + // Vue Node System Settings + { + id: 'Comfy.VueNodes.Enabled' as any, + category: ['Comfy', 'Vue Nodes'], + experimental: true, + name: 'Enable Vue node rendering', + tooltip: + 'Render nodes as Vue components instead of canvas elements. Experimental feature.', + type: 'boolean', + defaultValue: false + }, + { + id: 'Comfy.VueNodes.Widgets' as any, + category: ['Comfy', 'Vue Nodes', 'Widgets'], + experimental: true, + name: 'Enable Vue widgets', + tooltip: 'Render widgets as Vue components within Vue nodes.', + type: 'boolean', + defaultValue: true + }, + { + id: 'Comfy.VueNodes.ViewportCulling' as any, + category: ['Comfy', 'Vue Nodes', 'Performance'], + experimental: true, + name: 'Enable viewport culling', + tooltip: + 'Only render Vue nodes visible in viewport for better performance.', + type: 'boolean', + defaultValue: true + }, + { + id: 'Comfy.VueNodes.CullingMargin' as any, + category: ['Comfy', 'Vue Nodes', 'Performance'], + experimental: true, + name: 'Viewport culling margin', + tooltip: + 'Percentage of viewport to extend culling bounds (0.2 = 20% margin).', + type: 'slider', + defaultValue: 0.2, + attrs: { + min: 0, + max: 1, + step: 0.05 + } } ]