diff --git a/blocks/blocks.js b/blocks/blocks.js index 59ffa6eb..690ca564 100644 --- a/blocks/blocks.js +++ b/blocks/blocks.js @@ -197,6 +197,28 @@ export function handleMeshLifecycleChange(block, changeEvent) { return false; } +export function isValueInputDescendantOf(containerBlock, changedBlock) { + if (!containerBlock || !changedBlock) return false; + if (changedBlock.id === containerBlock.id) return true; + + let child = changedBlock; + while (child && child.id !== containerBlock.id) { + const parent = child.getParent?.(); + if (!parent) return false; + + const viaValueInput = (parent.inputList || []).some( + (inp) => + inp?.type === Blockly.INPUT_VALUE && + inp?.connection?.targetBlock?.() === child, + ); + + if (!viaValueInput) return false; + child = parent; + } + + return child?.id === containerBlock.id; +} + export function handleFieldOrChildChange(containerBlock, changeEvent) { if ( changeEvent.type !== Blockly.Events.BLOCK_CHANGE || @@ -214,55 +236,11 @@ export function handleFieldOrChildChange(containerBlock, changeEvent) { return true; } - const parent = changedBlock.getParent?.(); - if (parent && parent.id === containerBlock.id) { - if (changedBlock.nextConnection || changedBlock.previousConnection) - return false; + if (isValueInputDescendantOf(containerBlock, changedBlock)) { updateOrCreateMeshFromBlock(containerBlock, changeEvent); return true; } - if (containerBlock.type === "create_map") { - const materialBlock = containerBlock.getInputTargetBlock?.("MATERIAL"); - if (materialBlock) { - // If the MATERIAL block itself changed, forward. - if (changedBlock.id === materialBlock.id) { - updateOrCreateMeshFromBlock(containerBlock, changeEvent); - return true; - } - - // Forward if the change occurred in the MATERIAL subtree via VALUE inputs only (not statement chains). - const INPUT_VALUE = - typeof Blockly?.INPUT_VALUE !== "undefined" ? Blockly.INPUT_VALUE : 1; - - // Walk up from the changed block to the MATERIAL block, - // ensuring each step is through a VALUE input connection. - let node = changedBlock; - while (node && node !== materialBlock) { - const p = node.getParent?.(); - if (!p) break; - - const viaValueInput = (p.inputList || []).some( - (inp) => - inp?.type === INPUT_VALUE && - inp?.connection?.targetBlock?.() === node, - ); - - if (!viaValueInput) { - // Left the MATERIAL value-input subtree → do not forward. - node = null; - break; - } - node = p; - } - - if (node === materialBlock) { - updateOrCreateMeshFromBlock(containerBlock, changeEvent); - return true; - } - } - } - return false; } @@ -283,7 +261,11 @@ export function handleParentLinkedUpdate(containerBlock, changeEvent) { for (const changed of changedBlocks) { const parent = findCreateBlock(changed); - if (parent === containerBlock && changed) { + if ( + changed && + parent === containerBlock && + isValueInputDescendantOf(containerBlock, changed) + ) { if (!window.loadingCode) { updateOrCreateMeshFromBlock(containerBlock, changeEvent); } @@ -388,7 +370,12 @@ export function handleBlockChange(block, changeEvent, variableNamePrefix) { if (flock.blockDebug) console.log("This block is", block.id); // if (flock.blockDebug) console.log("The parent is", parent); if (flock.blockDebug) console.log("The type of this block is", block.type); - if (parents.includes(block)) { + if ( + changedBlock && + parents.includes(block) && + isValueInputDescendantOf(block, changedBlock) + ) { + // Only configuration inputs (value-input subtree) affect preview mesh; runtime statement blocks do not. const blockInWorkspace = Blockly.getMainWorkspace().getBlockById( block.id, );