Files
picoGraph/scripts/nodes/library/localVariables.js
Max Litruv Boonzaayer f917cf6ad5 Add initial Pico-8 cartridges for testing
- Created test_cart.p8 with basic drawing functionality and a print statement.
- Created test_unix.p8 with a simple initialization function.
2026-03-21 18:38:43 +11:00

154 lines
4.8 KiB
JavaScript

import { createNodeModule } from "../nodeTypes.js";
import {
getLocalVariableTypeOptions,
variablePropertyKey,
localVariableDefault,
LOCAL_VARIABLE_TYPE_IDS,
} from "../../types/TypeRegistry.js";
const LOCAL_TYPES = getLocalVariableTypeOptions();
const DEFAULT_LOCAL_TYPE = LOCAL_TYPES[0]?.value ?? "number";
const sanitizeType = (raw) => {
const candidate = typeof raw === "string" ? raw.trim().toLowerCase() : "";
return LOCAL_VARIABLE_TYPE_IDS.has(candidate) ? candidate : DEFAULT_LOCAL_TYPE;
};
const ensureName = (raw, fallback = "localVar") => {
const value = typeof raw === "string" ? raw.trim() : "";
return value.length ? value : fallback;
};
const resolveValuePropertyKey = variablePropertyKey;
const defaultValueForType = localVariableDefault;
const initializeLocalProperties = (properties, { includeValue }) => {
const type = sanitizeType(properties.variableType);
properties.variableType = type;
properties.name = ensureName(properties.name);
if (typeof properties.valueNumber !== "number") {
properties.valueNumber = Number.isFinite(Number(properties.valueNumber))
? Number(properties.valueNumber)
: 0;
}
if (typeof properties.valueString !== "string") {
properties.valueString = String(properties.valueString ?? "");
}
if (typeof properties.valueBoolean !== "boolean") {
properties.valueBoolean = Boolean(properties.valueBoolean);
}
if (typeof properties.valueTable !== "string") {
properties.valueTable = String(properties.valueTable ?? "{}");
}
if (
typeof properties.valueColor !== "number" ||
!Number.isFinite(properties.valueColor)
) {
const n = Number(properties.valueColor);
properties.valueColor = Number.isFinite(n)
? Math.max(0, Math.min(15, Math.round(n)))
: 7;
}
if (includeValue) {
const key = resolveValuePropertyKey(type);
const value = properties[key] ?? defaultValueForType(type);
properties[key] = value;
}
};
const normalizeLocalProperties = (properties, { includeValue }) => {
const type = sanitizeType(properties.variableType);
properties.variableType = type;
properties.name = ensureName(properties.name);
if (includeValue) {
const key = resolveValuePropertyKey(type);
const value = properties[key] ?? defaultValueForType(type);
properties[key] = value;
}
};
export const setLocalVariableNode = createNodeModule(
{
id: "set_local_var",
title: "Set Local",
category: "Logic",
description: "Declare or assign a local variable with an inline literal.",
searchTags: ["local", "set", "assign", "variable"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "value",
name: "Value",
direction: "input",
kind: "any",
description: "Optional override for the inline literal",
},
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
initializeProperties: (properties) => {
initializeLocalProperties(properties, { includeValue: true });
},
onPropertiesChanged: (properties) => {
normalizeLocalProperties(properties, { includeValue: true });
},
},
{
emitExec: ({
node,
indent,
indentLevel,
resolveValueInput,
sanitizeIdentifier,
emitNextExec,
formatLiteral,
}) => {
const type = sanitizeType(node.properties.variableType);
const name = sanitizeIdentifier(ensureName(node.properties.name));
const valueKey = resolveValuePropertyKey(type);
const inlineValue = node.properties[valueKey] ?? defaultValueForType(type);
const fallbackLiteral =
type === "table"
? String(inlineValue ?? "{}") || "{}"
: formatLiteral(type, inlineValue);
const valueExpression = resolveValueInput("value", fallbackLiteral);
const statement = `${indent(indentLevel)}local ${name} = ${valueExpression}`;
return [statement, ...emitNextExec("exec_out")];
},
}
);
export const getLocalVariableNode = createNodeModule(
{
id: "get_local_var",
title: "Get Local",
category: "Logic",
description: "Access a local variable declared earlier in the flow.",
searchTags: ["local", "get", "variable", "read"],
inputs: [],
outputs: [
{ id: "value", name: "Value", direction: "output", kind: "any" },
],
properties: [],
initializeProperties: (properties) => {
initializeLocalProperties(properties, { includeValue: false });
},
onPropertiesChanged: (properties) => {
normalizeLocalProperties(properties, { includeValue: false });
},
},
{
evaluateValue: ({ node, sanitizeIdentifier }) => {
return sanitizeIdentifier(ensureName(node.properties.name));
},
}
);
export const localVariableNodes = [setLocalVariableNode, getLocalVariableNode];