Split the object inspector, and sweep out the section banners
objectSection.ts had grown to 559 lines around three separable parts: the queries, the vector rows and the parent row. Four object commands repeated the same capture/restore preamble – applyCommands stays out, its five carry extra undo state whose restore order matters. 58 dashed banner comments are gone. The nine labels in nodes/index.ts stay: they are the only structure a flat 90-entry array has. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
11981b40d0
commit
3b3f374e10
11 files changed
+258
-244
No files matched your search
@@ -1,6 +1,12 @@
|
||||
import { newId } from '../ids';
|
||||
import { isSelfOrAncestor, localPositionFor, removeSubtrees, worldPosition } from '../model/hierarchy';
|
||||
import { captureObject, isLiveInstance, type ObjectMemo, restoreObject } from '../model/instance';
|
||||
import {
|
||||
captureObject,
|
||||
isLiveInstance,
|
||||
type ObjectMemo,
|
||||
type ObjectRef,
|
||||
restoreObject,
|
||||
} from '../model/instance';
|
||||
import { placementRejection } from '../model/placement';
|
||||
import { type Position, type PropertyValue, toPosition, type Vec2 } from '../model/Properties';
|
||||
import type { Project } from '../model/Project';
|
||||
@@ -17,6 +23,33 @@ import {
|
||||
requireStructural,
|
||||
} from './require';
|
||||
|
||||
/**
|
||||
* An edit to one placed object. The base captures the object before the edit and puts it back on
|
||||
* undo, so a subclass only says what changes. `applyCommands` deliberately does not use this: its
|
||||
* commands carry extra undo state whose restore order matters.
|
||||
*/
|
||||
abstract class ObjectEditCommand implements Command {
|
||||
abstract readonly label: string;
|
||||
private memo: ObjectMemo | undefined;
|
||||
|
||||
protected constructor(
|
||||
private readonly holderId: string,
|
||||
private readonly objectId: string,
|
||||
) {}
|
||||
|
||||
protected abstract apply(ref: ObjectRef, project: Project): void;
|
||||
|
||||
execute(project: Project): void {
|
||||
const ref = requireObjectRef(project, this.holderId, this.objectId);
|
||||
this.memo = captureObject(ref);
|
||||
this.apply(ref, project);
|
||||
}
|
||||
|
||||
undo(): void {
|
||||
if (this.memo) restoreObject(this.memo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The position is a world position; with a parent it is converted to the parent's local space.
|
||||
* Placing a container adds the container object alone – its content is resolved from the template
|
||||
@@ -88,91 +121,70 @@ export class RemoveSceneObjectCommand extends RemoveSceneObjectsCommand {
|
||||
* The previous position is read at execution time, so a caller that previewed the move must
|
||||
* restore the model before executing.
|
||||
*/
|
||||
export class MoveSceneObjectCommand implements Command {
|
||||
export class MoveSceneObjectCommand extends ObjectEditCommand {
|
||||
readonly label = 'Move object';
|
||||
private memo: ObjectMemo | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly holderId: string,
|
||||
private readonly objectId: string,
|
||||
holderId: string,
|
||||
objectId: string,
|
||||
private readonly position: Position,
|
||||
) {}
|
||||
|
||||
execute(project: Project): void {
|
||||
const ref = requireObjectRef(project, this.holderId, this.objectId);
|
||||
this.memo = captureObject(ref);
|
||||
ref.setPosition(this.position);
|
||||
) {
|
||||
super(holderId, objectId);
|
||||
}
|
||||
|
||||
undo(): void {
|
||||
if (this.memo) restoreObject(this.memo);
|
||||
protected override apply(ref: ObjectRef): void {
|
||||
ref.setPosition(this.position);
|
||||
}
|
||||
}
|
||||
|
||||
/** Editor-only: undoable like any other edit, but it changes nothing the game can see. */
|
||||
export class SetEditorOffsetCommand implements Command {
|
||||
export class SetEditorOffsetCommand extends ObjectEditCommand {
|
||||
readonly label = 'Editor offset';
|
||||
private memo: ObjectMemo | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly holderId: string,
|
||||
private readonly objectId: string,
|
||||
holderId: string,
|
||||
objectId: string,
|
||||
private readonly offset: Vec2,
|
||||
) {}
|
||||
) {
|
||||
super(holderId, objectId);
|
||||
}
|
||||
|
||||
execute(project: Project): void {
|
||||
const ref = requireObjectRef(project, this.holderId, this.objectId);
|
||||
this.memo = captureObject(ref);
|
||||
protected override apply(ref: ObjectRef): void {
|
||||
ref.setEditorOffset(this.offset);
|
||||
}
|
||||
|
||||
undo(): void {
|
||||
if (this.memo) restoreObject(this.memo);
|
||||
}
|
||||
}
|
||||
|
||||
export class RenameSceneObjectCommand implements Command {
|
||||
export class RenameSceneObjectCommand extends ObjectEditCommand {
|
||||
readonly label = 'Rename object';
|
||||
private memo: ObjectMemo | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly holderId: string,
|
||||
private readonly objectId: string,
|
||||
holderId: string,
|
||||
objectId: string,
|
||||
private readonly name: string,
|
||||
) {}
|
||||
|
||||
execute(project: Project): void {
|
||||
const ref = requireObjectRef(project, this.holderId, this.objectId);
|
||||
this.memo = captureObject(ref);
|
||||
ref.setName(this.name);
|
||||
) {
|
||||
super(holderId, objectId);
|
||||
}
|
||||
|
||||
undo(): void {
|
||||
if (this.memo) restoreObject(this.memo);
|
||||
protected override apply(ref: ObjectRef): void {
|
||||
ref.setName(this.name);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class OverrideCommand implements Command {
|
||||
private memo: ObjectMemo | undefined;
|
||||
|
||||
abstract class OverrideCommand extends ObjectEditCommand {
|
||||
protected constructor(
|
||||
private readonly holderId: string,
|
||||
private readonly objectId: string,
|
||||
holderId: string,
|
||||
objectId: string,
|
||||
protected readonly key: string,
|
||||
readonly label: string,
|
||||
) {}
|
||||
) {
|
||||
super(holderId, objectId);
|
||||
}
|
||||
|
||||
protected abstract nextValue(object: SceneObject, project: Project): PropertyValue | undefined;
|
||||
|
||||
execute(project: Project): void {
|
||||
const ref = requireObjectRef(project, this.holderId, this.objectId);
|
||||
this.memo = captureObject(ref);
|
||||
protected override apply(ref: ObjectRef, project: Project): void {
|
||||
ref.setOverride(this.key, this.nextValue(ref.object, project));
|
||||
}
|
||||
|
||||
undo(): void {
|
||||
if (this.memo) restoreObject(this.memo);
|
||||
}
|
||||
}
|
||||
|
||||
export class SetOverrideCommand extends OverrideCommand {
|
||||
|
||||
@@ -3,8 +3,6 @@ import type { PropertyDef } from '../../properties/PropertySchema';
|
||||
import type { NodeDef, PortDef } from '../NodeRegistry';
|
||||
import { asBoolean, asNumber } from '../values';
|
||||
|
||||
// --- ports -----------------------------------------------------------------------------------
|
||||
|
||||
export const exec = (key = 'exec', label = ''): PortDef => ({ key, label, type: 'exec' });
|
||||
export const num = (key: string, label = key): PortDef => ({ key, label, type: 'number' });
|
||||
export const bool = (key: string, label = key): PortDef => ({ key, label, type: 'boolean' });
|
||||
@@ -23,8 +21,6 @@ export const collisionOutputs = (): PortDef[] => [
|
||||
obj('collider'),
|
||||
];
|
||||
|
||||
// --- params ----------------------------------------------------------------------------------
|
||||
|
||||
export const keyParam: PropertyDef = { key: 'key', label: 'Key', kind: 'key', default: 'ArrowRight' };
|
||||
|
||||
/** Options are empty on purpose: the graph inspector fills in the behavior's variables. */
|
||||
@@ -39,8 +35,6 @@ export const variableParam: PropertyDef = {
|
||||
/** No `assetTypes`: any placeable asset is a valid answer here. */
|
||||
export const assetParam: PropertyDef = { key: 'asset', label: 'Asset', kind: 'asset', default: '' };
|
||||
|
||||
// --- node factories --------------------------------------------------------------------------
|
||||
|
||||
export function binaryMath(type: string, description: string, fn: (a: number, b: number) => number): NodeDef {
|
||||
return {
|
||||
type,
|
||||
|
||||
Reference in new issue
Block a user