Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/store/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,15 @@ export class CCConnectionStore extends EventEmitter<CCConnectionStoreEvents> {
this.emit("willUnregister", connection);
this.#connections.delete(connection.id);
}
// Announced as soon as the connections are gone, not when the transaction ends.
// Otherwise a listener of a change announced in between, such as a renderer
// subscribed to the node at one end, would look up a connection that is gone
// while the list of connections still has it. Removing a connection cascades
// to nothing, so its listeners see no half-removed state.
for (const connection of connections) {
this.emit("didUnregister", connection);
}
});
for (const connection of connections) {
this.emit("didUnregister", connection);
}
}

/**
Expand Down
55 changes: 55 additions & 0 deletions src/store/nodePin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,44 @@ describe("Node pin store", () => {
).toEqual({ isFixed: true, bitWidth: 8 });
});

it("should drop a removed input pin of an aggregate node from its output right away", () => {
const { store, rootComponent } = createRootStore();
const node = registerNode(store, rootComponent, intrinsics.aggregate);
const firstInputNodePin = nullthrows(
store.nodePins
.getManyByNodeId(node.id)
.find(
(pin) => pin.componentPinId === intrinsics.aggregate.inputPin.In.id,
),
);
store.nodePins.update(firstInputNodePin.id, { manualBitWidth: 5 });
const secondInputNodePin = CCNodePinStore.create({
nodeId: node.id,
componentPinId: intrinsics.aggregate.inputPin.In.id,
order: firstInputNodePin.order + 1,
manualBitWidth: 3,
});
store.nodePins.register(secondInputNodePin);
expect(
getNodePinBitWidth(
store,
node.id,
intrinsics.aggregate.outputPin.Out.id,
),
).toEqual({ isFixed: true, bitWidth: 8 });

// The removal is announced only when the transaction ends, but the pin is gone now
store.nodePins.unregister(secondInputNodePin.id);

expect(
getNodePinBitWidth(
store,
node.id,
intrinsics.aggregate.outputPin.Out.id,
),
).toEqual({ isFixed: true, bitWidth: 5 });
});

it("should sum up the manual bit widths of the output pins of a decompose node", () => {
const { store, rootComponent } = createRootStore();
const node = registerNode(store, rootComponent, intrinsics.decompose);
Expand Down Expand Up @@ -271,6 +309,23 @@ describe("Node pin store", () => {
expect(store.connections.getMany()).toHaveLength(0);
});

it("should announce a dropped connection before the config change that drops it", () => {
const { store, displayNode } = connectBroadcastToDisplay(20 * 15);
const events: string[] = [];
store.connections.on("didUnregister", () =>
events.push("connection removed"),
);
store.nodes.on("didUpdate", () => events.push("node updated"));

// A renderer of the connection subscribed to the display re-renders on "node
// updated", so by then the list of connections must no longer contain it
store.nodes.update(displayNode.id, {
config: { resolution: { x: 4, y: 3 } },
});

expect(events).toEqual(["connection removed", "node updated"]);
});

it("should keep the connections that stay consistent across a display config change", () => {
const { store, displayNode } = connectBroadcastToDisplay(20 * 15);

Expand Down
4 changes: 3 additions & 1 deletion src/store/nodePin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,10 @@ export class CCNodePinStore extends EventEmitter<CCNodePinStoreEvents> {
await this.#store.transactionManager.runInTransaction(() => {
this.emit("willUnregister", nodePin);
this.#nodePins.delete(nodePin.id);
// Its removal is announced only when the transaction ends, but the bit widths
// derived from it are stale from now on
this.#clearBitWidthCache();
});
this.#clearBitWidthCache();
this.emit("didUnregister", nodePin);
this.#markedAsDeleted.delete(id);
}
Expand Down
Loading