mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-04 08:50:33 +08:00
* Keep track of entities * Fix renaming * Niagara variables wip * Several niagara decode and test * Move nodeTemplate code to dedicated file, self node added * Move node decoding functions to dedicated files * Move pin decoding logic to dedicated files * Accept space separated keys in objects * Build * Prevent a crash in case of incomplete object * Avoid creating objects unnecessarily * types formatting * Initial metasound style * Common pcg nodes colors * Fix string serialization * Metasound new styles and fixes * More metasound styles and colors * WIP * Several fixes * More tests and fixes * Clean gitignore
647 lines
28 KiB
JavaScript
Executable File
647 lines
28 KiB
JavaScript
Executable File
import Parsernostrum from "parsernostrum"
|
|
import Configuration from "../Configuration.js"
|
|
import Utility from "../Utility.js"
|
|
import nodeColor from "../decoding/nodeColor.js"
|
|
import nodeIcon from "../decoding/nodeIcon.js"
|
|
import Grammar from "../serialization/Grammar.js"
|
|
import AttributeInfo from "./AttributeInfo.js"
|
|
import FunctionReferenceEntity from "./FunctionReferenceEntity.js"
|
|
import GuidEntity from "./GuidEntity.js"
|
|
import IEntity from "./IEntity.js"
|
|
import IdentifierEntity from "./IdentifierEntity.js"
|
|
import IntegerEntity from "./IntegerEntity.js"
|
|
import LinearColorEntity from "./LinearColorEntity.js"
|
|
import MacroGraphReferenceEntity from "./MacroGraphReferenceEntity.js"
|
|
import MirroredEntity from "./MirroredEntity.js"
|
|
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
|
|
import PinEntity from "./PinEntity.js"
|
|
import ScriptVariableEntity from "./ScriptVariableEntity.js"
|
|
import SymbolEntity from "./SymbolEntity.js"
|
|
import Union from "./Union.js"
|
|
import UnknownPinEntity from "./UnknownPinEntity.js"
|
|
import VariableReferenceEntity from "./VariableReferenceEntity.js"
|
|
import nodeVariadic from "../decoding/nodeVariadic.js"
|
|
|
|
export default class ObjectEntity extends IEntity {
|
|
|
|
static attributes = {
|
|
...super.attributes,
|
|
isExported: new AttributeInfo({
|
|
type: Boolean,
|
|
ignored: true,
|
|
}),
|
|
Class: AttributeInfo.createType(ObjectReferenceEntity),
|
|
Name: AttributeInfo.createType(String),
|
|
Archetype: AttributeInfo.createType(ObjectReferenceEntity),
|
|
ExportPath: AttributeInfo.createType(ObjectReferenceEntity),
|
|
ObjectRef: AttributeInfo.createType(ObjectReferenceEntity),
|
|
BlueprintElementType: AttributeInfo.createType(ObjectReferenceEntity),
|
|
BlueprintElementInstance: AttributeInfo.createType(ObjectReferenceEntity),
|
|
PinTags: new AttributeInfo({
|
|
type: [null],
|
|
inlined: true,
|
|
}),
|
|
PinNames: new AttributeInfo({
|
|
type: [String],
|
|
inlined: true,
|
|
}),
|
|
AxisKey: AttributeInfo.createType(SymbolEntity),
|
|
InputAxisKey: AttributeInfo.createType(SymbolEntity),
|
|
InputName: AttributeInfo.createType(String),
|
|
InputType: AttributeInfo.createType(SymbolEntity),
|
|
NumAdditionalInputs: AttributeInfo.createType(Number),
|
|
bIsPureFunc: AttributeInfo.createType(Boolean),
|
|
bIsConstFunc: AttributeInfo.createType(Boolean),
|
|
bIsCaseSensitive: AttributeInfo.createType(Boolean),
|
|
VariableReference: AttributeInfo.createType(VariableReferenceEntity),
|
|
SelfContextInfo: AttributeInfo.createType(SymbolEntity),
|
|
DelegatePropertyName: AttributeInfo.createType(String),
|
|
DelegateOwnerClass: AttributeInfo.createType(ObjectReferenceEntity),
|
|
ComponentPropertyName: AttributeInfo.createType(String),
|
|
EventReference: AttributeInfo.createType(FunctionReferenceEntity),
|
|
FunctionReference: AttributeInfo.createType(FunctionReferenceEntity),
|
|
FunctionScript: AttributeInfo.createType(ObjectReferenceEntity),
|
|
CustomFunctionName: AttributeInfo.createType(String),
|
|
TargetType: AttributeInfo.createType(ObjectReferenceEntity),
|
|
MacroGraphReference: AttributeInfo.createType(MacroGraphReferenceEntity),
|
|
Enum: AttributeInfo.createType(ObjectReferenceEntity),
|
|
EnumEntries: new AttributeInfo({
|
|
type: [String],
|
|
inlined: true,
|
|
}),
|
|
InputKey: AttributeInfo.createType(SymbolEntity),
|
|
OpName: AttributeInfo.createType(String),
|
|
CachedChangeId: AttributeInfo.createType(GuidEntity),
|
|
FunctionDisplayName: AttributeInfo.createType(String),
|
|
AddedPins: new AttributeInfo({
|
|
type: [UnknownPinEntity],
|
|
default: () => [],
|
|
inlined: true,
|
|
silent: true,
|
|
}),
|
|
ChangeId: AttributeInfo.createType(GuidEntity),
|
|
MaterialFunction: AttributeInfo.createType(ObjectReferenceEntity),
|
|
bOverrideFunction: AttributeInfo.createType(Boolean),
|
|
bInternalEvent: AttributeInfo.createType(Boolean),
|
|
bConsumeInput: AttributeInfo.createType(Boolean),
|
|
bExecuteWhenPaused: AttributeInfo.createType(Boolean),
|
|
bOverrideParentBinding: AttributeInfo.createType(Boolean),
|
|
bControl: AttributeInfo.createType(Boolean),
|
|
bAlt: AttributeInfo.createType(Boolean),
|
|
bShift: AttributeInfo.createType(Boolean),
|
|
bCommand: AttributeInfo.createType(Boolean),
|
|
CommentColor: AttributeInfo.createType(LinearColorEntity),
|
|
bCommentBubbleVisible_InDetailsPanel: AttributeInfo.createType(Boolean),
|
|
bColorCommentBubble: AttributeInfo.createType(Boolean),
|
|
ProxyFactoryFunctionName: AttributeInfo.createType(String),
|
|
ProxyFactoryClass: AttributeInfo.createType(ObjectReferenceEntity),
|
|
ProxyClass: AttributeInfo.createType(ObjectReferenceEntity),
|
|
StructType: AttributeInfo.createType(ObjectReferenceEntity),
|
|
MaterialExpression: AttributeInfo.createType(ObjectReferenceEntity),
|
|
MaterialExpressionComment: AttributeInfo.createType(ObjectReferenceEntity),
|
|
MoveMode: AttributeInfo.createType(SymbolEntity),
|
|
TimelineName: AttributeInfo.createType(String),
|
|
TimelineGuid: AttributeInfo.createType(GuidEntity),
|
|
SizeX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
|
SizeY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
|
Text: AttributeInfo.createType(new MirroredEntity(String)),
|
|
MaterialExpressionEditorX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
|
MaterialExpressionEditorY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
|
NodeTitle: AttributeInfo.createType(String),
|
|
NodeTitleColor: AttributeInfo.createType(LinearColorEntity),
|
|
PositionX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
|
PositionY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
|
SettingsInterface: AttributeInfo.createType(ObjectReferenceEntity),
|
|
PCGNode: AttributeInfo.createType(ObjectReferenceEntity),
|
|
HiGenGridSize: AttributeInfo.createType(SymbolEntity),
|
|
Operation: AttributeInfo.createType(SymbolEntity),
|
|
NodePosX: AttributeInfo.createType(IntegerEntity),
|
|
NodePosY: AttributeInfo.createType(IntegerEntity),
|
|
NodeHeight: AttributeInfo.createType(IntegerEntity),
|
|
NodeWidth: AttributeInfo.createType(IntegerEntity),
|
|
Graph: AttributeInfo.createType(ObjectReferenceEntity),
|
|
SubgraphInstance: AttributeInfo.createType(String),
|
|
InputPins: new AttributeInfo({
|
|
type: [ObjectReferenceEntity],
|
|
inlined: true,
|
|
}),
|
|
OutputPins: new AttributeInfo({
|
|
type: [ObjectReferenceEntity],
|
|
inlined: true,
|
|
}),
|
|
bExposeToLibrary: AttributeInfo.createType(Boolean),
|
|
bCanRenameNode: AttributeInfo.createType(Boolean),
|
|
bCommentBubblePinned: AttributeInfo.createType(Boolean),
|
|
bCommentBubbleVisible: AttributeInfo.createType(Boolean),
|
|
NodeComment: AttributeInfo.createType(String),
|
|
AdvancedPinDisplay: AttributeInfo.createType(IdentifierEntity),
|
|
DelegateReference: AttributeInfo.createType(VariableReferenceEntity),
|
|
EnabledState: AttributeInfo.createType(IdentifierEntity),
|
|
NodeGuid: AttributeInfo.createType(GuidEntity),
|
|
ErrorType: AttributeInfo.createType(IntegerEntity),
|
|
ErrorMsg: AttributeInfo.createType(String),
|
|
ScriptVariables: new AttributeInfo({
|
|
type: [ScriptVariableEntity],
|
|
inlined: true,
|
|
}),
|
|
Node: AttributeInfo.createType(new MirroredEntity(ObjectReferenceEntity)),
|
|
ExportedNodes: AttributeInfo.createType(String),
|
|
CustomProperties: AttributeInfo.createType([new Union(PinEntity, UnknownPinEntity)]),
|
|
}
|
|
static nameRegex = /^(\w+?)(?:_(\d+))?$/
|
|
static customPropertyGrammar = Parsernostrum.seq(
|
|
Parsernostrum.reg(/CustomProperties\s+/),
|
|
Grammar.grammarFor(
|
|
undefined,
|
|
this.attributes.CustomProperties.type[0]
|
|
),
|
|
).map(([_0, pin]) => values => {
|
|
if (!values.CustomProperties) {
|
|
values.CustomProperties = []
|
|
}
|
|
values.CustomProperties.push(pin)
|
|
})
|
|
static inlinedArrayEntryGrammar = Parsernostrum.seq(
|
|
Parsernostrum.alt(
|
|
Grammar.symbolQuoted.map(v => [v, true]),
|
|
Grammar.symbol.map(v => [v, false]),
|
|
),
|
|
Parsernostrum.reg(
|
|
new RegExp(`\\s*\\(\\s*(\\d+)\\s*\\)\\s*\\=\\s*`),
|
|
1
|
|
).map(Number)
|
|
)
|
|
.chain(
|
|
/** @param {[[String, Boolean], Number]} param */
|
|
([[symbol, quoted], index]) =>
|
|
Grammar.grammarFor(this.attributes[symbol])
|
|
.map(currentValue =>
|
|
values => {
|
|
(values[symbol] ??= [])[index] = currentValue
|
|
Utility.objectSet(values, ["attributes", symbol, "quoted"], quoted)
|
|
if (!this.attributes[symbol]?.inlined) {
|
|
if (!values.attributes) {
|
|
IEntity.defineAttributes(values, {})
|
|
}
|
|
Utility.objectSet(values, ["attributes", symbol, "type"], [currentValue.constructor])
|
|
Utility.objectSet(values, ["attributes", symbol, "inlined"], true)
|
|
}
|
|
}
|
|
)
|
|
)
|
|
static grammar = this.createGrammar()
|
|
|
|
static createSubObjectGrammar() {
|
|
return Parsernostrum.lazy(() => this.grammar)
|
|
.map(object =>
|
|
values => values[Configuration.subObjectAttributeNameFromEntity(object)] = object
|
|
)
|
|
}
|
|
|
|
static createGrammar() {
|
|
return Parsernostrum.seq(
|
|
Parsernostrum.reg(/Begin +Object/),
|
|
Parsernostrum.seq(
|
|
Parsernostrum.whitespace,
|
|
Parsernostrum.alt(
|
|
this.createSubObjectGrammar(),
|
|
this.customPropertyGrammar,
|
|
Grammar.createAttributeGrammar(this, Parsernostrum.reg(Grammar.Regex.MultipleWordsSymbols)),
|
|
Grammar.createAttributeGrammar(this, Grammar.attributeNameQuoted, undefined, (obj, k, v) =>
|
|
Utility.objectSet(obj, ["attributes", ...k, "quoted"], true)
|
|
),
|
|
this.inlinedArrayEntryGrammar,
|
|
)
|
|
)
|
|
.map(([_0, entry]) => entry)
|
|
.many(),
|
|
Parsernostrum.reg(/\s+End +Object/),
|
|
)
|
|
.map(([_0, attributes, _2]) => {
|
|
const values = {}
|
|
attributes.forEach(attributeSetter => attributeSetter(values))
|
|
return new this(values)
|
|
})
|
|
}
|
|
|
|
static getMultipleObjectsGrammar() {
|
|
return Parsernostrum.seq(
|
|
Parsernostrum.whitespaceOpt,
|
|
this.grammar,
|
|
Parsernostrum.seq(
|
|
Parsernostrum.whitespace,
|
|
this.grammar,
|
|
)
|
|
.map(([_0, object]) => object)
|
|
.many(),
|
|
Parsernostrum.whitespaceOpt
|
|
)
|
|
.map(([_0, first, remaining, _4]) => [first, ...remaining])
|
|
}
|
|
|
|
/** @type {String} */
|
|
#class
|
|
|
|
constructor(values = {}, suppressWarns = false) {
|
|
if ("NodePosX" in values !== "NodePosY" in values) {
|
|
const entries = Object.entries(values)
|
|
const [key, position] = "NodePosX" in values
|
|
? ["NodePosY", Object.keys(values).indexOf("NodePosX") + 1]
|
|
: ["NodePosX", Object.keys(values).indexOf("NodePosY")]
|
|
const entry = [key, new (AttributeInfo.getAttribute(values, key, "type", ObjectEntity))()]
|
|
entries.splice(position, 0, entry)
|
|
values = Object.fromEntries(entries)
|
|
}
|
|
super(values, suppressWarns)
|
|
|
|
// Attributes not assigned a strong type in attributes because the names are too generic
|
|
/** @type {Number | MirroredEntity<Boolean>} */ this.R
|
|
/** @type {Number | MirroredEntity<Boolean>} */ this.G
|
|
/** @type {Number | MirroredEntity<Boolean>} */ this.B
|
|
/** @type {Number | MirroredEntity<Boolean>} */ this.A
|
|
|
|
// Attributes
|
|
/** @type {(PinEntity | UnknownPinEntity)[]} */ this.CustomProperties
|
|
/** @type {Boolean} */ this.bIsPureFunc
|
|
/** @type {Boolean} */ this.isExported
|
|
/** @type {FunctionReferenceEntity} */ this.ComponentPropertyName
|
|
/** @type {FunctionReferenceEntity} */ this.EventReference
|
|
/** @type {FunctionReferenceEntity} */ this.FunctionReference
|
|
/** @type {IdentifierEntity} */ this.AdvancedPinDisplay
|
|
/** @type {IdentifierEntity} */ this.EnabledState
|
|
/** @type {IntegerEntity} */ this.NodeHeight
|
|
/** @type {IntegerEntity} */ this.NodePosX
|
|
/** @type {IntegerEntity} */ this.NodePosY
|
|
/** @type {IntegerEntity} */ this.NodeWidth
|
|
/** @type {LinearColorEntity} */ this.CommentColor
|
|
/** @type {LinearColorEntity} */ this.NodeTitleColor
|
|
/** @type {MacroGraphReferenceEntity} */ this.MacroGraphReference
|
|
/** @type {MirroredEntity} */ this.MaterialExpressionEditorX
|
|
/** @type {MirroredEntity} */ this.MaterialExpressionEditorY
|
|
/** @type {MirroredEntity} */ this.SizeX
|
|
/** @type {MirroredEntity} */ this.SizeY
|
|
/** @type {MirroredEntity} */ this.Text
|
|
/** @type {MirroredEntity<IntegerEntity>} */ this.PositionX
|
|
/** @type {MirroredEntity<IntegerEntity>} */ this.PositionY
|
|
/** @type {MirroredEntity<ObjectReferenceEntity>} */ this.Node
|
|
/** @type {null[]} */ this.PinTags
|
|
/** @type {Number} */ this.NumAdditionalInputs
|
|
/** @type {ObjectReferenceEntity[]} */ this.InputPins
|
|
/** @type {ObjectReferenceEntity[]} */ this.OutputPins
|
|
/** @type {ObjectReferenceEntity} */ this.Archetype
|
|
/** @type {ObjectReferenceEntity} */ this.BlueprintElementInstance
|
|
/** @type {ObjectReferenceEntity} */ this.BlueprintElementType
|
|
/** @type {ObjectReferenceEntity} */ this.Class
|
|
/** @type {ObjectReferenceEntity} */ this.Enum
|
|
/** @type {ObjectReferenceEntity} */ this.ExportPath
|
|
/** @type {ObjectReferenceEntity} */ this.FunctionScript
|
|
/** @type {ObjectReferenceEntity} */ this.Graph
|
|
/** @type {ObjectReferenceEntity} */ this.MaterialExpression
|
|
/** @type {ObjectReferenceEntity} */ this.MaterialExpressionComment
|
|
/** @type {ObjectReferenceEntity} */ this.MaterialFunction
|
|
/** @type {ObjectReferenceEntity} */ this.ObjectRef
|
|
/** @type {ObjectReferenceEntity} */ this.PCGNode
|
|
/** @type {ObjectReferenceEntity} */ this.SettingsInterface
|
|
/** @type {ObjectReferenceEntity} */ this.StructType
|
|
/** @type {ObjectReferenceEntity} */ this.TargetType
|
|
/** @type {ScriptVariableEntity[]} */ this.ScriptVariables
|
|
/** @type {String[]} */ this.EnumEntries
|
|
/** @type {String[]} */ this.PinNames
|
|
/** @type {String} */ this.CustomFunctionName
|
|
/** @type {String} */ this.DelegatePropertyName
|
|
/** @type {String} */ this.ExportedNodes
|
|
/** @type {String} */ this.FunctionDisplayName
|
|
/** @type {String} */ this.InputName
|
|
/** @type {String} */ this.Name
|
|
/** @type {String} */ this.NodeComment
|
|
/** @type {String} */ this.NodeTitle
|
|
/** @type {String} */ this.Operation
|
|
/** @type {String} */ this.OpName
|
|
/** @type {String} */ this.ProxyFactoryFunctionName
|
|
/** @type {String} */ this.SubgraphInstance
|
|
/** @type {String} */ this.Text
|
|
/** @type {SymbolEntity} */ this.AxisKey
|
|
/** @type {SymbolEntity} */ this.HiGenGridSize
|
|
/** @type {SymbolEntity} */ this.InputAxisKey
|
|
/** @type {SymbolEntity} */ this.InputKey
|
|
/** @type {SymbolEntity} */ this.InputType
|
|
/** @type {UnknownPinEntity[]} */ this.AddedPins
|
|
/** @type {VariableReferenceEntity} */ this.DelegateReference
|
|
/** @type {VariableReferenceEntity} */ this.VariableReference
|
|
|
|
// Legacy nodes pins
|
|
if (this["Pins"] instanceof Array) {
|
|
this["Pins"].forEach(
|
|
/** @param {ObjectReferenceEntity} objectReference */
|
|
objectReference => {
|
|
const pinObject = this[Configuration.subObjectAttributeNameFromReference(objectReference, true)]
|
|
if (pinObject) {
|
|
const pinEntity = PinEntity.fromLegacyObject(pinObject)
|
|
pinEntity.LinkedTo = []
|
|
this.getCustomproperties(true).push(pinEntity)
|
|
Utility.objectSet(this, ["attributes", "CustomProperties", "ignored"], true)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
/** @type {ObjectEntity} */
|
|
const materialSubobject = this.getMaterialSubobject()
|
|
if (materialSubobject) {
|
|
const obj = materialSubobject
|
|
obj.SizeX !== undefined && (obj.SizeX.getter = () => this.NodeWidth)
|
|
obj.SizeY && (obj.SizeY.getter = () => this.NodeHeight)
|
|
obj.Text && (obj.Text.getter = () => this.NodeComment)
|
|
obj.MaterialExpressionEditorX && (obj.MaterialExpressionEditorX.getter = () => this.NodePosX)
|
|
obj.MaterialExpressionEditorY && (obj.MaterialExpressionEditorY.getter = () => this.NodePosY)
|
|
if (this.getType() === Configuration.paths.materialExpressionComponentMask) {
|
|
// The following attributes are too generic therefore not assigned a MirroredEntity
|
|
const rgbaPins = Configuration.rgba.map(pinName =>
|
|
this.getPinEntities().find(pin => pin.PinName === pinName && (pin.recomputesNodeTitleOnChange = true))
|
|
)
|
|
const attribute = {}
|
|
obj.R = new MirroredEntity(Boolean, () => rgbaPins[0].DefaultValue)
|
|
obj.G = new MirroredEntity(Boolean, () => rgbaPins[1].DefaultValue)
|
|
obj.B = new MirroredEntity(Boolean, () => rgbaPins[2].DefaultValue)
|
|
obj.A = new MirroredEntity(Boolean, () => rgbaPins[3].DefaultValue)
|
|
Utility.objectSet(obj, ["attributes", "R", "default"], false)
|
|
Utility.objectSet(obj, ["attributes", "R", "silent"], true)
|
|
Utility.objectSet(obj, ["attributes", "G", "default"], false)
|
|
Utility.objectSet(obj, ["attributes", "G", "silent"], true)
|
|
Utility.objectSet(obj, ["attributes", "B", "default"], false)
|
|
Utility.objectSet(obj, ["attributes", "B", "silent"], true)
|
|
Utility.objectSet(obj, ["attributes", "A", "default"], false)
|
|
Utility.objectSet(obj, ["attributes", "A", "silent"], true)
|
|
obj._keys = [...Configuration.rgba, ...Object.keys(obj).filter(k => !Configuration.rgba.includes(k))]
|
|
}
|
|
}
|
|
/** @type {ObjectEntity} */
|
|
const pcgObject = this.getPcgSubobject()
|
|
if (pcgObject) {
|
|
pcgObject.PositionX && (pcgObject.PositionX.getter = () => this.NodePosX)
|
|
pcgObject.PositionY && (pcgObject.PositionY.getter = () => this.NodePosY)
|
|
pcgObject.getSubobjects().forEach(
|
|
/** @param {ObjectEntity} obj */
|
|
obj => {
|
|
if (obj.Node !== undefined) {
|
|
const nodeRef = obj.Node.get()
|
|
if (
|
|
nodeRef.type === this.PCGNode.type
|
|
&& nodeRef.path === `${this.Name}.${this.PCGNode.path}`
|
|
) {
|
|
obj.Node.getter = () => new ObjectReferenceEntity({
|
|
type: this.PCGNode.type,
|
|
path: `${this.Name}.${this.PCGNode.path}`,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
}
|
|
let inputIndex = 0
|
|
let outputIndex = 0
|
|
this.CustomProperties?.forEach((pinEntity, i) => {
|
|
pinEntity.objectEntity = this
|
|
pinEntity.pinIndex = pinEntity.isInput()
|
|
? inputIndex++
|
|
: pinEntity.isOutput()
|
|
? outputIndex++
|
|
: i
|
|
})
|
|
}
|
|
|
|
getClass() {
|
|
if (!this.#class) {
|
|
this.#class = (this.Class?.path ? this.Class.path : this.Class?.type)
|
|
?? (this.ExportPath?.path ? this.ExportPath.path : this.ExportPath?.type)
|
|
?? ""
|
|
if (this.#class && !this.#class.startsWith("/")) {
|
|
// Old path names did not start with /Script or /Engine, check tests/resources/LegacyNodes.js
|
|
let path = Object.values(Configuration.paths).find(path => path.endsWith("." + this.#class))
|
|
if (path) {
|
|
this.#class = path
|
|
}
|
|
}
|
|
}
|
|
return this.#class
|
|
}
|
|
|
|
getType() {
|
|
let classValue = this.getClass()
|
|
if (this.MacroGraphReference?.MacroGraph?.path) {
|
|
return this.MacroGraphReference.MacroGraph.path
|
|
}
|
|
if (this.MaterialExpression) {
|
|
return this.MaterialExpression.type
|
|
}
|
|
return classValue
|
|
}
|
|
|
|
getObjectName(dropCounter = false) {
|
|
if (dropCounter) {
|
|
return this.getNameAndCounter()[0]
|
|
}
|
|
return this.Name
|
|
}
|
|
|
|
/** @returns {[String, Number]} */
|
|
getNameAndCounter() {
|
|
const result = this.getObjectName().match(ObjectEntity.nameRegex)
|
|
let name = ""
|
|
let counter = null
|
|
return result
|
|
? [result[1] ?? "", parseInt(result[2] ?? "0")]
|
|
: ["", 0]
|
|
}
|
|
|
|
getCounter() {
|
|
return this.getNameAndCounter()[1]
|
|
}
|
|
|
|
getNodeWidth() {
|
|
return this.NodeWidth
|
|
?? this.isComment() ? Configuration.defaultCommentWidth : undefined
|
|
}
|
|
|
|
/** @param {Number} value */
|
|
setNodeWidth(value) {
|
|
if (!this.NodeWidth) {
|
|
this.NodeWidth = new IntegerEntity()
|
|
}
|
|
this.NodeWidth.value = value
|
|
}
|
|
|
|
getNodeHeight() {
|
|
return this.NodeHeight
|
|
?? this.isComment() ? Configuration.defaultCommentHeight : undefined
|
|
}
|
|
|
|
/** @param {Number} value */
|
|
setNodeHeight(value) {
|
|
if (!this.NodeHeight) {
|
|
this.NodeHeight = new IntegerEntity()
|
|
}
|
|
this.NodeHeight.value = value
|
|
}
|
|
|
|
getNodePosX() {
|
|
return this.NodePosX?.value ?? 0
|
|
}
|
|
|
|
/** @param {Number} value */
|
|
setNodePosX(value) {
|
|
if (!this.NodePosX) {
|
|
this.NodePosX = new IntegerEntity()
|
|
}
|
|
this.NodePosX.value = Math.round(value)
|
|
}
|
|
|
|
getNodePosY() {
|
|
return this.NodePosY?.value ?? 0
|
|
}
|
|
|
|
/** @param {Number} value */
|
|
setNodePosY(value) {
|
|
if (!this.NodePosY) {
|
|
this.NodePosY = new IntegerEntity()
|
|
}
|
|
this.NodePosY.value = Math.round(value)
|
|
}
|
|
|
|
getCustomproperties(canCreate = false) {
|
|
if (canCreate && !this.CustomProperties) {
|
|
this.CustomProperties = []
|
|
}
|
|
return this.CustomProperties ?? []
|
|
}
|
|
|
|
/** @returns {PinEntity[]} */
|
|
getPinEntities() {
|
|
return this.getCustomproperties().filter(v => v.constructor === PinEntity)
|
|
}
|
|
|
|
/** @returns {ObjectEntity[]} */
|
|
getSubobjects() {
|
|
return Object.keys(this)
|
|
.filter(k => k.startsWith(Configuration.subObjectAttributeNamePrefix))
|
|
.flatMap(k => [this[k], .../** @type {ObjectEntity} */(this[k]).getSubobjects()])
|
|
}
|
|
|
|
switchTarget() {
|
|
const switchMatch = this.getClass().match(Configuration.switchTargetPattern)
|
|
if (switchMatch) {
|
|
return switchMatch[1]
|
|
}
|
|
}
|
|
|
|
isEvent() {
|
|
switch (this.getClass()) {
|
|
case Configuration.paths.actorBoundEvent:
|
|
case Configuration.paths.componentBoundEvent:
|
|
case Configuration.paths.customEvent:
|
|
case Configuration.paths.event:
|
|
case Configuration.paths.inputAxisKeyEvent:
|
|
case Configuration.paths.inputVectorAxisEvent:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
isComment() {
|
|
switch (this.getClass()) {
|
|
case Configuration.paths.comment:
|
|
case Configuration.paths.materialGraphNodeComment:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
isMaterial() {
|
|
|
|
return this.getClass() === Configuration.paths.materialGraphNode
|
|
// return [
|
|
// Configuration.paths.materialExpressionConstant,
|
|
// Configuration.paths.materialExpressionConstant2Vector,
|
|
// Configuration.paths.materialExpressionConstant3Vector,
|
|
// Configuration.paths.materialExpressionConstant4Vector,
|
|
// Configuration.paths.materialExpressionLogarithm,
|
|
// Configuration.paths.materialExpressionLogarithm10,
|
|
// Configuration.paths.materialExpressionLogarithm2,
|
|
// Configuration.paths.materialExpressionMaterialFunctionCall,
|
|
// Configuration.paths.materialExpressionSquareRoot,
|
|
// Configuration.paths.materialExpressionTextureCoordinate,
|
|
// Configuration.paths.materialExpressionTextureSample,
|
|
// Configuration.paths.materialGraphNode,
|
|
// Configuration.paths.materialGraphNodeComment,
|
|
// ]
|
|
// .includes(this.getClass())
|
|
}
|
|
|
|
/** @return {ObjectEntity} */
|
|
getMaterialSubobject() {
|
|
const expression = this.MaterialExpression ?? this.MaterialExpressionComment
|
|
return expression
|
|
? this[Configuration.subObjectAttributeNameFromReference(expression, true)]
|
|
: null
|
|
}
|
|
|
|
isPcg() {
|
|
return this.getClass() === Configuration.paths.pcgEditorGraphNode
|
|
|| this.getPcgSubobject()
|
|
}
|
|
|
|
isNiagara() {
|
|
return this.Class && (this.Class.type ? this.Class.type : this.Class.path)?.startsWith("/Script/NiagaraEditor.")
|
|
}
|
|
|
|
/** @return {ObjectEntity} */
|
|
getPcgSubobject() {
|
|
const node = this.PCGNode
|
|
return node
|
|
? this[Configuration.subObjectAttributeNameFromReference(node, true)]
|
|
: null
|
|
}
|
|
|
|
/** @return {ObjectEntity} */
|
|
getSettingsObject() {
|
|
const settings = this.SettingsInterface
|
|
return settings
|
|
? this[Configuration.subObjectAttributeNameFromReference(settings, true)]
|
|
: null
|
|
}
|
|
|
|
/** @return {ObjectEntity} */
|
|
getSubgraphObject() {
|
|
const name = this.SubgraphInstance
|
|
return name
|
|
? this[Configuration.subObjectAttributeNameFromName(name)]
|
|
: null
|
|
}
|
|
|
|
isDevelopmentOnly() {
|
|
const nodeClass = this.getClass()
|
|
return this.EnabledState?.toString() === "DevelopmentOnly"
|
|
|| nodeClass.includes("Debug", Math.max(0, nodeClass.lastIndexOf(".")))
|
|
}
|
|
|
|
getHIDAttribute() {
|
|
return this.InputKey ?? this.AxisKey ?? this.InputAxisKey
|
|
}
|
|
|
|
getDelegatePin() {
|
|
return this.getCustomproperties().find(pin => pin.PinType.PinCategory === "delegate")
|
|
}
|
|
|
|
nodeColor() {
|
|
return nodeColor(this)
|
|
}
|
|
|
|
nodeIcon() {
|
|
return nodeIcon(this)
|
|
}
|
|
|
|
additionalPinInserter() {
|
|
return nodeVariadic(this)
|
|
}
|
|
}
|