Refactor round 2: fold duplicated command and inspector code
- applyCommands sit on ObjectEditCommand with a revert hook instead of five copies of the same preamble and undo - actionIf replaces six identical Reset/Apply menu blocks, addNameField the three name rows, assetLink the two asset links - requireStructuralObject replaces ten two-line preambles and drops the duplicate holder lookup - __gm.objectsOf had no caller; the SMB remnant in e2e.sh is gone Proven: check.sh 797 tests, full e2e 633 checks, smokes 24/19/20 against the same bundle. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
6471671f7d
commit
ce42d16657
13 files changed
+139
-223
No files matched your search
@@ -20,15 +20,15 @@ import {
|
||||
requireObjectRef,
|
||||
requirePropDef,
|
||||
requireHolder,
|
||||
requireStructural,
|
||||
requireStructuralObject,
|
||||
} 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.
|
||||
* undo, so a subclass only says what changes – and, if it wrote somewhere else too, how to take
|
||||
* that back (`revert`).
|
||||
*/
|
||||
abstract class ObjectEditCommand implements Command {
|
||||
export abstract class ObjectEditCommand implements Command {
|
||||
abstract readonly label: string;
|
||||
private memo: ObjectMemo | undefined;
|
||||
|
||||
@@ -39,6 +39,8 @@ abstract class ObjectEditCommand implements Command {
|
||||
|
||||
protected abstract apply(ref: ObjectRef, project: Project): void;
|
||||
|
||||
protected revert(): void {}
|
||||
|
||||
execute(project: Project): void {
|
||||
const ref = requireObjectRef(project, this.holderId, this.objectId);
|
||||
this.memo = captureObject(ref);
|
||||
@@ -46,6 +48,7 @@ abstract class ObjectEditCommand implements Command {
|
||||
}
|
||||
|
||||
undo(): void {
|
||||
this.revert();
|
||||
if (this.memo) restoreObject(this.memo);
|
||||
}
|
||||
}
|
||||
@@ -71,10 +74,7 @@ export class PlaceAssetCommand implements Command {
|
||||
const asset = requireAsset(project, this.assetId);
|
||||
const rejection = placementRejection(project, holder, asset);
|
||||
if (rejection) throw new CommandError(rejection);
|
||||
if (this.parentId) {
|
||||
requireObject(project, this.holderId, this.parentId);
|
||||
requireStructural(project, holder, this.parentId);
|
||||
}
|
||||
if (this.parentId) requireStructuralObject(project, holder, this.parentId);
|
||||
const local = localPositionFor(holder, this.parentId, toPosition(this.position));
|
||||
holder.objects.push(createSceneObject(this.objectId, this.assetId, local, this.parentId));
|
||||
}
|
||||
@@ -99,10 +99,7 @@ export class RemoveSceneObjectsCommand implements Command {
|
||||
|
||||
execute(project: Project): void {
|
||||
const holder = requireHolder(project, this.holderId);
|
||||
for (const id of this.objectIds) {
|
||||
requireStructural(project, holder, id);
|
||||
requireObject(project, this.holderId, id);
|
||||
}
|
||||
for (const id of this.objectIds) requireStructuralObject(project, holder, id);
|
||||
this.removed = removeSubtrees(holder, this.objectIds);
|
||||
}
|
||||
|
||||
@@ -226,14 +223,12 @@ export class ReorderObjectCommand implements Command {
|
||||
|
||||
execute(project: Project): void {
|
||||
const holder = requireHolder(project, this.holderId);
|
||||
requireStructural(project, holder, this.objectId);
|
||||
const object = requireObject(project, this.holderId, this.objectId);
|
||||
const object = requireStructuralObject(project, holder, this.objectId);
|
||||
if (this.beforeId === this.objectId)
|
||||
throw new CommandError('An object cannot be moved in front of itself');
|
||||
let at = holder.objects.length;
|
||||
if (this.beforeId) {
|
||||
requireStructural(project, holder, this.beforeId);
|
||||
const before = requireObject(project, this.holderId, this.beforeId);
|
||||
const before = requireStructuralObject(project, holder, this.beforeId);
|
||||
if (before.parentId !== object.parentId)
|
||||
throw new CommandError('An object can only be reordered among its own siblings');
|
||||
at = holder.objects.indexOf(before);
|
||||
@@ -271,12 +266,10 @@ export class SetParentCommand implements Command {
|
||||
|
||||
execute(project: Project): void {
|
||||
const holder = requireHolder(project, this.holderId);
|
||||
requireStructural(project, holder, this.objectId);
|
||||
const object = requireObject(project, this.holderId, this.objectId);
|
||||
const object = requireStructuralObject(project, holder, this.objectId);
|
||||
if (this.parentId) {
|
||||
if (this.parentId === this.objectId) throw new CommandError('An object cannot be its own parent');
|
||||
requireStructural(project, holder, this.parentId);
|
||||
if (isLiveInstance(project, holder, requireObject(project, this.holderId, this.parentId)))
|
||||
if (isLiveInstance(project, holder, requireStructuralObject(project, holder, this.parentId)))
|
||||
throw new CommandError('A placed container shows its template; unpack it to put objects inside');
|
||||
if (isSelfOrAncestor(holder, this.objectId, this.parentId))
|
||||
throw new CommandError('An object cannot be parented to one of its own children');
|
||||
|
||||
Reference in new issue
Block a user