[API] Add LLink.resolve static / instance methods (#974)

- `LLink.resolve`: Resolves all IDs on the link to their respective
objects (node IDs, slot indexes)
- `LinkNetwork.getLink`: a more concise pattern to resolve links
This commit is contained in:
filtered
2025-04-27 06:51:41 +10:00
committed by GitHub
parent 8e8818c24d
commit b3d030e36b
3 changed files with 70 additions and 1 deletions

View File

@@ -1174,6 +1174,17 @@ export class LGraph implements LinkNetwork, Serialisable<SerialisableGraph> {
}
}
/**
* Finds the link with the provided ID.
* @param id ID of link to find
* @returns The link with the provided {@link id}, otherwise `undefined`. Always returns `undefined` if `id` is nullish.
*/
getLink(id: null | undefined): undefined
getLink(id: LinkId | null | undefined): LLink | undefined
getLink(id: LinkId | null | undefined): LLink | undefined {
return id == null ? undefined : this._links.get(id)
}
/**
* Returns a reroute by ID, or `undefined` if the ID is `null` or `undefined`.
* @param id ID of reroute to return

View File

@@ -1,5 +1,7 @@
import type {
CanvasColour,
INodeInputSlot,
INodeOutputSlot,
ISlotType,
LinkNetwork,
LinkSegment,
@@ -20,7 +22,15 @@ export type SerialisedLLinkArray = [
type: ISlotType,
]
type BasicReadonlyNetwork = Pick<ReadonlyLinkNetwork, "getNodeById" | "links" | "floatingLinks">
interface ResolvedConnection {
inputNode: LGraphNode | undefined
outputNode: LGraphNode | undefined
input: INodeInputSlot | undefined
output: INodeOutputSlot | undefined
link: LLink
}
type BasicReadonlyNetwork = Pick<ReadonlyLinkNetwork, "getNodeById" | "links" | "getLink">
// this is the class in charge of storing link information
export class LLink implements LinkSegment, Serialisable<SerialisableLLink> {
@@ -180,6 +190,52 @@ export class LLink implements LinkSegment, Serialisable<SerialisableLLink> {
return network.getNodeById(id) ?? undefined
}
/**
* Resolves a link ID to the link, node, and slot objects.
* @param linkId The {@link id} of the link to resolve
* @param network The link network to search
* @returns An object containing the input and output nodes, as well as the input and output slots.
* @remarks This method is heavier than others; it will always resolve all objects.
* Whilst the performance difference should in most cases be negligible,
* it is recommended to use simpler methods where appropriate.
*/
static resolve(linkId: LinkId | null | undefined, network: BasicReadonlyNetwork): ResolvedConnection | undefined {
return network.getLink(linkId)?.resolve(network)
}
/**
* Resolves a list of link IDs to the link, node, and slot objects.
* Discards invalid link IDs.
* @param linkIds An iterable of link {@link id}s to resolve
* @param network The link network to search
* @returns An array of resolved connections. If a link is not found, it is not included in the array.
* @see {@link LLink.resolve}
*/
static resolveMany(linkIds: Iterable<LinkId>, network: BasicReadonlyNetwork): ResolvedConnection[] {
const resolved: ResolvedConnection[] = []
for (const id of linkIds) {
const r = network.getLink(id)?.resolve(network)
if (r) resolved.push(r)
}
return resolved
}
/**
* Resolves the primitive ID values stored in the link to the referenced objects.
* @param network The link network to search
* @returns An object containing the input and output nodes, as well as the input and output slots.
* @remarks This method is heavier than others; it will always resolve all objects.
* Whilst the performance difference should in most cases be negligible,
* it is recommended to use simpler methods where appropriate.
*/
resolve(network: BasicReadonlyNetwork): ResolvedConnection {
const inputNode = this.target_id === -1 ? undefined : network.getNodeById(this.target_id) ?? undefined
const outputNode = this.origin_id === -1 ? undefined : network.getNodeById(this.origin_id) ?? undefined
const input = inputNode?.inputs[this.target_slot]
const output = outputNode?.outputs[this.origin_slot]
return { inputNode, outputNode, input, output, link: this }
}
configure(o: LLink | SerialisedLLinkArray) {
if (Array.isArray(o)) {
this.id = o[0]

View File

@@ -127,6 +127,8 @@ export interface ReadonlyLinkNetwork {
readonly reroutes: ReadonlyMap<RerouteId, Reroute>
readonly floatingLinks: ReadonlyMap<LinkId, LLink>
getNodeById(id: NodeId | null | undefined): LGraphNode | null
getLink(id: null | undefined): undefined
getLink(id: LinkId | null | undefined): LLink | undefined
getReroute(parentId: null | undefined): undefined
getReroute(parentId: RerouteId | null | undefined): Reroute | undefined
}