Files
ueblueprint/js/decoding/nodeVariadic.js
BarsDev 6ba2705386 Large refactoring and new nodes
* Fix node reference when changing elements

* Fix ScriptVariables parsing

* Fix invariant text and niagara types

* Niagara convert nodes

* Move node tests to own files

* More Niagara tests

* Niagara float and smaller fixes

* More Decoding

* More decoding

* WIP

* Float is real

* WIP

* More types and colors

* Test case and small polish

* WIP

* WIP

* Fix niagara script variables merging

* Fix Niagara variables

* Fixing mirrored ExportPath

* Fix Export paths name adjustments

* Simplify arc calculation

* Simplify a bit arc calculation

* source / destionation => origin / target

* Minor refactoring

* Fix switched link position

* Rename some properties for uniformity

* Fix input escape

* Simplify test

* About window

* Dialog backdrop style

* About dialog touches

* Remove dependency and minot improvement

* Light mode

* Fix link location and css small improvement

* Link direction and minor fixes

* Some minor fixes and refactoring

* Refactoring WIP

* Shorting repetitive bits

* More tests

* Simplify linking tests
2025-02-07 00:36:03 +02:00

163 lines
7.0 KiB
JavaScript
Executable File

import Configuration from "../Configuration.js"
import ArrayEntity from "../entity/ArrayEntity.js"
import GuidEntity from "../entity/GuidEntity.js"
import NaturalNumberEntity from "../entity/NaturalNumberEntity.js"
import PinEntity from "../entity/PinEntity.js"
import StringEntity from "../entity/StringEntity.js"
/** @param {PinEntity} pinEntity */
const indexFromUpperCaseLetterName = pinEntity =>
pinEntity.PinName?.toString().match(/^\s*([A-Z])\s*$/)?.[1]?.charCodeAt(0) - "A".charCodeAt(0)
const p = Configuration.paths
/** @param {ObjectEntity} entity */
export default function nodeVariadic(entity) {
/** @type {() => PinEntity[]} */
let pinEntities
/** @type {(pinEntity: PinEntity) => Number} */
let pinIndexFromEntity
/** @type {(newPinIndex: Number, minIndex: Number, maxIndex: Number, newPin: PinEntity) => String} */
let pinNameFromIndex
const type = entity.getType()
let prefix
let name
switch (type) {
case p.commutativeAssociativeBinaryOperator:
case p.promotableOperator:
name = entity.FunctionReference?.MemberName?.toString()
switch (name) {
default:
if (
!name?.startsWith("Add_")
&& !name?.startsWith("Subtract_")
&& !name?.startsWith("Multiply_")
&& !name?.startsWith("Divide_")
) {
break
}
case "And_Int64Int64":
case "And_IntInt":
case "BMax":
case "BMin":
case "BooleanAND":
case "BooleanNAND":
case "BooleanOR":
case "Concat_StrStr":
case "FMax":
case "FMin":
case "Max":
case "MaxInt64":
case "Min":
case "MinInt64":
case "Or_Int64Int64":
case "Or_IntInt":
pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isInput())
pinIndexFromEntity ??= indexFromUpperCaseLetterName
pinNameFromIndex ??= (index, min = -1, max = -1) => {
const result = String.fromCharCode(index >= 0 ? index : max + "A".charCodeAt(0) + 1)
entity.NumAdditionalInputs = new NaturalNumberEntity(pinEntities().length - 1)
return result
}
break
}
break
case p.executionSequence:
prefix ??= "Then"
case p.multiGate:
prefix ??= "Out"
pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isOutput())
pinIndexFromEntity ??= pinEntity => Number(
pinEntity.PinName?.toString().match(new RegExp(String.raw`^\s*${prefix}[_\s]+(\d+)\s*$`, "i"))?.[1]
)
pinNameFromIndex ??= (index, min = -1, max = -1, newPin) =>
`${prefix} ${index >= 0 ? index : min > 0 ? `${prefix} 0` : max + 1}`
break
// case p.niagaraNodeOp:
// pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isInput())
// pinIndexFromEntity ??= indexFromUpperCaseLetterName
// pinNameFromIndex ??= (index, min = -1, max = -1, newPin) => {
// const result = String.fromCharCode(index >= 0 ? index : max + "A".charCodeAt(0) + 1)
// entity.AddedPins ??= []
// entity.AddedPins.push(newPin)
// return result
// }
// break
case p.switchInteger:
pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isOutput())
pinIndexFromEntity ??= pinEntity => Number(pinEntity.PinName?.toString().match(/^\s*(\d+)\s*$/)?.[1])
pinNameFromIndex ??= (index, min = -1, max = -1, newPin) => (index < 0 ? max + 1 : index).toString()
break
case p.switchGameplayTag:
pinNameFromIndex ??= (index, min = -1, max = -1, newPin) => {
const result = `Case_${index >= 0 ? index : min > 0 ? "0" : max + 1}`
entity.PinNames ??= new ArrayEntity()
entity.PinNames.valueOf().push(new StringEntity(result))
delete entity.PinTags.valueOf()[entity.PinTags.length - 1]
entity.PinTags.valueOf()[entity.PinTags.length] = null
return result
}
case p.switchName:
case p.switchString:
pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isOutput())
pinIndexFromEntity ??= pinEntity => Number(pinEntity.PinName.toString().match(/^\s*Case[_\s]+(\d+)\s*$/i)?.[1])
pinNameFromIndex ??= (index, min = -1, max = -1, newPin) => {
const result = `Case_${index >= 0 ? index : min > 0 ? "0" : max + 1}`
entity.PinNames ??= new ArrayEntity()
entity.PinNames.valueOf().push(new StringEntity(result))
return result
}
break
}
if (pinEntities) {
return () => {
let min = Number.MAX_SAFE_INTEGER
let max = Number.MIN_SAFE_INTEGER
let values = []
const modelPin = pinEntities().reduce(
(acc, cur) => {
const value = pinIndexFromEntity(cur)
if (!isNaN(value)) {
values.push(value)
min = Math.min(value, min)
if (value > max) {
max = value
return cur
}
} else if (acc === undefined) {
return cur
}
return acc
},
undefined
)
if (min === Number.MAX_SAFE_INTEGER || max === Number.MIN_SAFE_INTEGER) {
min = undefined
max = undefined
}
if (!modelPin) {
return null
}
values.sort((a, b) => a < b ? -1 : a === b ? 0 : 1)
let prev = values[0]
let index = values.findIndex(
// Search for a gap
value => {
const result = value - prev > 1
prev = value
return result
}
)
const newPin = new PinEntity(modelPin)
newPin.PinId = new GuidEntity()
newPin.PinName = new StringEntity(pinNameFromIndex(index, min, max, newPin))
newPin.PinToolTip = undefined
if (newPin.DefaultValue) {
// @ts-expect-error
newPin.DefaultValue = new (newPin.DefaultValue.constructor)()
}
entity.getCustomproperties(true).push(newPin)
return newPin
}
}
}