Skip to content

Commit

Permalink
[graph] extract interact
Browse files Browse the repository at this point in the history
  • Loading branch information
xieyuheng committed Jul 29, 2023
1 parent f111373 commit cdfefc6
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 96 deletions.
6 changes: 2 additions & 4 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
[graph] extract `interact`
[graph] `ActiveEdge` should be type instead of class

quit using `ActiveEdge`

`ActiveEdge` should be type instead of class
[maybe] quit using `ActiveEdge`

use new syntax

Expand Down
92 changes: 1 addition & 91 deletions src/lang/graph/ActiveEdge.ts
Original file line number Diff line number Diff line change
@@ -1,100 +1,10 @@
import { InternalError } from "../errors"
import { Net, Node, Port } from "../graph"
import { Mod } from "../mod"
import { Port } from "../graph"
import { Rule } from "../rule"
import { netConnect } from "./netConnect"
import { netRemoveEdge } from "./netRemoveEdge"
import { netRemoveNode } from "./netRemoveNode"

export class ActiveEdge {
constructor(
public start: Port,
public end: Port,
public rule: Rule,
) {}

interact(mod: Mod, net: Net): void {
// NOTE The state of action.
const input: Array<Port> = []
const output: Array<Port> = []

disconnectNode(net, this.end.node, input, output)
disconnectNode(net, this.start.node, input, output)

net.portStack.push(...input)

// NOTE Reconnect by rule.
for (const word of this.rule.words) {
word.apply(mod, net)
}

reconnectOutput(net, output)
}
}

function disconnectNode(
net: Net,
node: Node,
input: Array<Port>,
output: Array<Port>,
): void {
disconnectInput(net, node.input, input)
disconnectOutput(net, node.output, output)
netRemoveNode(net, node)
}

function disconnectInput(
net: Net,
ports: Array<Port>,
input: Array<Port>,
): void {
for (const port of ports) {
if (!port.isPrincipal) {
if (port.connection === undefined) {
throw new InternalError(
"I meet a port without connection during disconnecting input.",
)
}

input.push(port.connection.port)
netRemoveEdge(net, port.connection.edge)
}
}
}

function disconnectOutput(
net: Net,
ports: Array<Port>,
output: Array<Port>,
): void {
for (const port of ports) {
if (!port.isPrincipal) {
if (port.connection === undefined) {
throw new InternalError(
"I meet a port without connection during disconnecting output.",
)
}

output.unshift(port.connection.port)
netRemoveEdge(net, port.connection.edge)
}
}
}

function reconnectOutput(net: Net, output: Array<Port>): void {
if (net.portStack.length !== output.length) {
throw new InternalError(
[
`Resulting ports doesn't match prepared output ports`,
` resulting ports length: ${net.portStack.length}`,
` prepared output ports length: ${output.length}`,
].join("\n"),
)
}

while (net.portStack.length > 0) {
const start = net.portStack.pop() as Port
const end = output.pop() as Port
netConnect(net, start, end)
}
}
91 changes: 91 additions & 0 deletions src/lang/graph/interact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { InternalError } from "../errors"
import { ActiveEdge, Net, Node, Port } from "../graph"
import { Mod } from "../mod"
import { netConnect } from "./netConnect"
import { netRemoveEdge } from "./netRemoveEdge"
import { netRemoveNode } from "./netRemoveNode"

export function interact(mod: Mod, net: Net, activeEdge: ActiveEdge): void {
// NOTE The state of action.
const input: Array<Port> = []
const output: Array<Port> = []

disconnectNode(net, activeEdge.end.node, input, output)
disconnectNode(net, activeEdge.start.node, input, output)

net.portStack.push(...input)

// NOTE Reconnect by rule.
for (const word of activeEdge.rule.words) {
word.apply(mod, net)
}

reconnectOutput(net, output)
}

function disconnectNode(
net: Net,
node: Node,
input: Array<Port>,
output: Array<Port>,
): void {
disconnectInput(net, node.input, input)
disconnectOutput(net, node.output, output)
netRemoveNode(net, node)
}

function disconnectInput(
net: Net,
ports: Array<Port>,
input: Array<Port>,
): void {
for (const port of ports) {
if (!port.isPrincipal) {
if (port.connection === undefined) {
throw new InternalError(
"I meet a port without connection during disconnecting input.",
)
}

input.push(port.connection.port)
netRemoveEdge(net, port.connection.edge)
}
}
}

function disconnectOutput(
net: Net,
ports: Array<Port>,
output: Array<Port>,
): void {
for (const port of ports) {
if (!port.isPrincipal) {
if (port.connection === undefined) {
throw new InternalError(
"I meet a port without connection during disconnecting output.",
)
}

output.unshift(port.connection.port)
netRemoveEdge(net, port.connection.edge)
}
}
}

function reconnectOutput(net: Net, output: Array<Port>): void {
if (net.portStack.length !== output.length) {
throw new InternalError(
[
`Resulting ports doesn't match prepared output ports`,
` resulting ports length: ${net.portStack.length}`,
` prepared output ports length: ${output.length}`,
].join("\n"),
)
}

while (net.portStack.length > 0) {
const start = net.portStack.pop() as Port
const end = output.pop() as Port
netConnect(net, start, end)
}
}
3 changes: 2 additions & 1 deletion src/lang/graph/netRun.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { InternalError } from "../errors"
import { Net } from "./Net"
import { interact } from "./interact"
import { netCleanUpWires } from "./netCleanUpWires"
import { netCloseFreePorts } from "./netCloseFreePorts"
import { netReleaseFreePorts } from "./netReleaseFreePorts"
Expand All @@ -24,6 +25,6 @@ function netStep(net: Net): void {
if (activeEdge === undefined) {
return
} else {
activeEdge.interact(net.mod, net)
interact(net.mod, net, activeEdge)
}
}

0 comments on commit cdfefc6

Please sign in to comment.