Fix findUsages/undo/node-lookup bugs, split Viewport and Editor, share command and inspector helpers

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5 committed 2026-09-08 09:22:49 +02:00
1 parent 1eb28314cf
commit f140c2fd77
58 files changed
+1969 -1171

No files matched your search

+13 -11
View File
@@ -1,6 +1,7 @@
import type { PropertyValue } from '../model/Properties';
import { findUsages, type Project } from '../model/Project';
import { isCommonProp, type PropertyDef, type VariableKind, variableDef } from '../properties/PropertySchema';
import { type Removed, removeFirst, restoreAt } from '../util/list';
import { type Command, CommandError } from './Command';
import { requireBehavior } from './require';
@@ -32,8 +33,8 @@ export class AddVariableCommand implements Command {
/** Removes a variable together with its default and every instance override. */
export class RemoveVariableCommand implements Command {
readonly label: string;
private removed?: { def: PropertyDef; index: number; value: PropertyValue | undefined };
private overrides: { sceneId: string; objectId: string; value: PropertyValue }[] = [];
private removed?: { def: Removed<PropertyDef>; value: PropertyValue | undefined };
private overrides: { holderId: string; objectId: string; value: PropertyValue }[] = [];
constructor(private readonly assetId: string, private readonly key: string) {
this.label = `Remove variable ${key}`;
@@ -41,17 +42,15 @@ export class RemoveVariableCommand implements Command {
execute(project: Project): void {
const asset = requireBehavior(project, this.assetId);
const index = asset.variables.findIndex((v) => v.key === this.key);
const def = asset.variables[index];
const def = removeFirst(asset.variables, (v) => v.key === this.key);
if (!def) throw new CommandError(`Variable "${this.key}" not found`);
this.removed = { def, index, value: asset.props[this.key] };
asset.variables.splice(index, 1);
this.removed = { def, value: asset.props[this.key] };
delete asset.props[this.key];
this.overrides = [];
for (const { scene, object } of findUsages(project, this.assetId)) {
for (const { holder, object } of findUsages(project, this.assetId)) {
const value = object.overrides[this.key];
if (value === undefined) continue;
this.overrides.push({ sceneId: scene.id, objectId: object.id, value });
this.overrides.push({ holderId: holder.id, objectId: object.id, value });
delete object.overrides[this.key];
}
}
@@ -59,17 +58,20 @@ export class RemoveVariableCommand implements Command {
undo(project: Project): void {
if (!this.removed) return;
const asset = requireBehavior(project, this.assetId);
asset.variables.splice(this.removed.index, 0, this.removed.def);
restoreAt(asset.variables, [this.removed.def]);
if (this.removed.value !== undefined) asset.props[this.key] = this.removed.value;
const usages = findUsages(project, this.assetId);
for (const o of this.overrides) {
const object = usages.find((u) => u.scene.id === o.sceneId && u.object.id === o.objectId)?.object;
const object = usages.find((u) => u.holder.id === o.holderId && u.object.id === o.objectId)?.object;
if (object) object.overrides[this.key] = o.value;
}
}
}
/** Renames a variable everywhere: definition, default, instance overrides and graph nodes referring to it. */
/**
* Renames a variable everywhere: definition, default, instance overrides (in scenes and in
* container templates) and graph nodes referring to it.
*/
export class RenameVariableCommand implements Command {
readonly label: string;