Let a variable hold a list
A variable could only be a number, a text or a yes/no, so every set of values had to be smuggled through a string - which is where Tetris got its unreadable "03066326048763714" colours from. A list is now a value of its own, with an item kind (number, text, yes/no, colour) that decides how the inspector reads the one comma-separated line it is typed as, and eight nodes to work with: List, Fill, Count, Item at, Set item, Sub list, Join lists, Index of. Two traps came with it. An array is typeof 'object', so every place that told a value from an entity had to learn the difference, or a list would have been passed around as a game object. And a value was compared by identity in three places - with lists that marks everything as an overridden property after each reload, so those comparisons now compare contents. There is no list of objects: a list is written to the project file and an object is a live handle that no reload survives. A set of objects stays a list of names. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c6f907b4e0
commit
a9c3111377
25 files changed
+469
-25
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import type { PropertyBag, PropertyValue } from '../model/Properties';
|
||||
import { isList, type ListValue, type PropertyBag, type PropertyValue } from '../model/Properties';
|
||||
import type { EntityHandle } from './NodeContext';
|
||||
|
||||
/** A value travelling along a data edge. Objects are live entity handles (play mode only). */
|
||||
@@ -11,9 +11,24 @@ export function asNumber(value: Value | undefined): number {
|
||||
const n = Number(value);
|
||||
return Number.isFinite(n) ? n : 0;
|
||||
}
|
||||
if (isList(value)) return value.length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Anything that is not a list reads as a one-item list, so a lone value can feed a list input. */
|
||||
export function asList(value: Value | undefined): ListValue {
|
||||
if (isList(value)) return value;
|
||||
if (value === null || value === undefined) return [];
|
||||
return typeof value === 'object' ? [value.name] : [value];
|
||||
}
|
||||
|
||||
/** A value narrowed to what a list may hold: handles and nested lists have no stored form. */
|
||||
export function asListItem(value: Value | undefined): number | string | boolean {
|
||||
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string') return value;
|
||||
if (value === null || value === undefined) return 0;
|
||||
return asString(value);
|
||||
}
|
||||
|
||||
export function asBoolean(value: Value | undefined): boolean {
|
||||
if (typeof value === 'string') return value !== '' && value !== 'false' && value !== '0';
|
||||
return Boolean(value);
|
||||
@@ -22,12 +37,14 @@ export function asBoolean(value: Value | undefined): boolean {
|
||||
/** Entities read as their name, so a handle can be logged or joined into text directly. */
|
||||
export function asString(value: Value | undefined): string {
|
||||
if (value === null || value === undefined) return '';
|
||||
if (isList(value)) return value.join(', ');
|
||||
if (typeof value === 'object') return value.name;
|
||||
return String(value);
|
||||
}
|
||||
|
||||
export function asEntity(value: Value | undefined): EntityHandle | null {
|
||||
return value && typeof value === 'object' ? value : null;
|
||||
if (!value || typeof value !== 'object' || isList(value)) return null;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +53,8 @@ export function asEntity(value: Value | undefined): EntityHandle | null {
|
||||
*/
|
||||
export function writeTyped(bag: PropertyBag, key: string, value: Value | undefined): void {
|
||||
const current = bag[key];
|
||||
if (typeof current === 'number') bag[key] = asNumber(value);
|
||||
if (isList(current)) bag[key] = asList(value);
|
||||
else if (typeof current === 'number') bag[key] = asNumber(value);
|
||||
else if (typeof current === 'boolean') bag[key] = asBoolean(value);
|
||||
else bag[key] = asString(value);
|
||||
}
|
||||
Reference in new issue
Block a user