mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-03 23:55:04 +08:00
Attributes initialization refactoring (#19)
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,8 +2,6 @@ node_modules/
|
||||
package-lock.json
|
||||
localhost*
|
||||
*.git
|
||||
cypress/screenshots
|
||||
cypress/videos
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
|
||||
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -6,6 +6,10 @@
|
||||
120
|
||||
],
|
||||
"typescript.tsserver.experimental.enableProjectDiagnostics": true,
|
||||
"js/ts.implicitProjectConfig.target": "ES2022",
|
||||
"js/ts.implicitProjectConfig.target": "ESNext",
|
||||
"typescript.format.semicolons": "remove",
|
||||
"javascript.preferences.importModuleSpecifier": "relative",
|
||||
"javascript.preferences.importModuleSpecifierEnding": "js",
|
||||
"javascript.updateImportsOnFileMove.enabled": "always",
|
||||
"editor.formatOnSave": true,
|
||||
}
|
||||
|
||||
6295
dist/ueblueprint.js
vendored
6295
dist/ueblueprint.js
vendored
File diff suppressed because it is too large
Load Diff
10
dist/ueblueprint.min.js
vendored
10
dist/ueblueprint.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -153,6 +153,7 @@ export default class Configuration {
|
||||
makeMap: "/Script/BlueprintGraph.K2Node_MakeMap",
|
||||
makeSet: "/Script/BlueprintGraph.K2Node_MakeSet",
|
||||
makeStruct: "/Script/BlueprintGraph.K2Node_MakeStruct",
|
||||
materialExpressionComponentMask: "/Script/Engine.MaterialExpressionComponentMask",
|
||||
materialExpressionConstant: "/Script/Engine.MaterialExpressionConstant",
|
||||
materialExpressionConstant2Vector: "/Script/Engine.MaterialExpressionConstant2Vector",
|
||||
materialExpressionConstant3Vector: "/Script/Engine.MaterialExpressionConstant3Vector",
|
||||
@@ -328,6 +329,8 @@ export default class Configuration {
|
||||
"Alt",
|
||||
"Meta",
|
||||
]
|
||||
/** @type {["R", "G", "B", "A"]} */
|
||||
static rgba = ["R", "G", "B", "A"]
|
||||
static Keys = {
|
||||
/* UE name: JS name */
|
||||
"Backspace": "Backspace",
|
||||
|
||||
@@ -189,6 +189,12 @@ export default class Utility {
|
||||
* @param {Attribute} b
|
||||
*/
|
||||
static equals(a, b) {
|
||||
while (a instanceof MirroredEntity) {
|
||||
a = a.get()
|
||||
}
|
||||
while (b instanceof MirroredEntity) {
|
||||
b = b.get()
|
||||
}
|
||||
// Here we cannot check both instanceof IEntity because this would introduce a circular include dependency
|
||||
if (/** @type {IEntity?} */(a)?.equals && /** @type {IEntity?} */(b)?.equals) {
|
||||
return /** @type {IEntity} */(a).equals(/** @type {IEntity} */(b))
|
||||
@@ -423,6 +429,11 @@ export default class Utility {
|
||||
return Array.from({ length: Math.ceil((end - begin) / step) }, (_, i) => begin + (i * step))
|
||||
}
|
||||
|
||||
/** @param {String[]} words */
|
||||
static getFirstWordOrder(words) {
|
||||
return new RegExp(/\s*/.source + words.join(/[^\n]+\n\s*/.source) + /\s*/.source)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} element
|
||||
* @param {String} value
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import CommentNodeTemplate from "../template/node/CommentNodeTemplate.js"
|
||||
import Configuration from "../Configuration.js"
|
||||
import EventNodeTemplate from "../template/node/EventNodeTemplate.js"
|
||||
import Utility from "../Utility.js"
|
||||
import IdentifierEntity from "../entity/IdentifierEntity.js"
|
||||
import ISelectableDraggableElement from "./ISelectableDraggableElement.js"
|
||||
import KnotNodeTemplate from "../template/node/KnotNodeTemplate.js"
|
||||
import NodeTemplate from "../template/node/NodeTemplate.js"
|
||||
import ObjectEntity from "../entity/ObjectEntity.js"
|
||||
import PinEntity from "../entity/PinEntity.js"
|
||||
import PinReferenceEntity from "../entity/PinReferenceEntity.js"
|
||||
import SerializerFactory from "../serialization/SerializerFactory.js"
|
||||
import Utility from "../Utility.js"
|
||||
import CommentNodeTemplate from "../template/node/CommentNodeTemplate.js"
|
||||
import EventNodeTemplate from "../template/node/EventNodeTemplate.js"
|
||||
import KnotNodeTemplate from "../template/node/KnotNodeTemplate.js"
|
||||
import NodeTemplate from "../template/node/NodeTemplate.js"
|
||||
import VariableAccessNodeTemplate from "../template/node/VariableAccessNodeTemplate.js"
|
||||
import VariableConversionNodeTemplate from "../template/node/VariableConversionNodeTemplate.js"
|
||||
import VariableOperationNodeTemplate from "../template/node/VariableOperationNodeTemplate.js"
|
||||
import ISelectableDraggableElement from "./ISelectableDraggableElement.js"
|
||||
|
||||
/** @extends {ISelectableDraggableElement<ObjectEntity, NodeTemplate>} */
|
||||
export default class NodeElement extends ISelectableDraggableElement {
|
||||
@@ -200,15 +200,15 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
}
|
||||
|
||||
initialize(entity = new ObjectEntity(), template = new (NodeElement.getTypeTemplate(entity))()) {
|
||||
this.typePath = entity.getType()
|
||||
this.nodeTitle = entity.getObjectName()
|
||||
this.advancedPinDisplay = entity.AdvancedPinDisplay?.toString()
|
||||
this.enabledState = entity.EnabledState
|
||||
this.nodeDisplayName = entity.nodeDisplayName()
|
||||
this.pureFunction = entity.bIsPureFunc
|
||||
this.dragLinkObjects = []
|
||||
super.initialize(entity, template)
|
||||
this.#pins = this.template.createPinElements()
|
||||
this.typePath = this.entity.getType()
|
||||
this.nodeTitle = this.entity.getObjectName()
|
||||
this.advancedPinDisplay = this.entity.AdvancedPinDisplay?.toString()
|
||||
this.enabledState = this.entity.EnabledState
|
||||
this.nodeDisplayName = this.getNodeDisplayName()
|
||||
this.pureFunction = this.entity.bIsPureFunc
|
||||
this.dragLinkObjects = []
|
||||
super.setLocation(this.entity.getNodePosX(), this.entity.getNodePosY())
|
||||
if (this.entity.NodeWidth && this.entity.NodeHeight) {
|
||||
this.sizeX = this.entity.NodeWidth.value
|
||||
@@ -260,8 +260,8 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
return this.entity.getObjectName()
|
||||
}
|
||||
|
||||
getNodeDisplayName() {
|
||||
return this.entity.nodeDisplayName()
|
||||
computeNodeDisplayName() {
|
||||
this.nodeDisplayName = this.entity.nodeDisplayName()
|
||||
}
|
||||
|
||||
/** @param {Number} value */
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import BoolPinTemplate from "../template/pin/BoolPinTemplate.js"
|
||||
import Configuration from "../Configuration.js"
|
||||
import ElementFactory from "./ElementFactory.js"
|
||||
import EnumPinTemplate from "../template/pin/EnumPinTemplate.js"
|
||||
import ExecPinTemplate from "../template/pin/ExecPinTemplate.js"
|
||||
import Utility from "../Utility.js"
|
||||
import GuidEntity from "../entity/GuidEntity.js"
|
||||
import IElement from "./IElement.js"
|
||||
import Int64PinTemplate from "../template/pin/Int64PinTemplate.js"
|
||||
import IntPinTemplate from "../template/pin/IntPinTemplate.js"
|
||||
import LinearColorEntity from "../entity/LinearColorEntity.js"
|
||||
import LinearColorPinTemplate from "../template/pin/LinearColorPinTemplate.js"
|
||||
import NamePinTemplate from "../template/pin/NamePinTemplate.js"
|
||||
import PinEntity from "../entity/PinEntity.js"
|
||||
import PinReferenceEntity from "../entity/PinReferenceEntity.js"
|
||||
import BoolPinTemplate from "../template/pin/BoolPinTemplate.js"
|
||||
import EnumPinTemplate from "../template/pin/EnumPinTemplate.js"
|
||||
import ExecPinTemplate from "../template/pin/ExecPinTemplate.js"
|
||||
import Int64PinTemplate from "../template/pin/Int64PinTemplate.js"
|
||||
import IntPinTemplate from "../template/pin/IntPinTemplate.js"
|
||||
import LinearColorPinTemplate from "../template/pin/LinearColorPinTemplate.js"
|
||||
import NamePinTemplate from "../template/pin/NamePinTemplate.js"
|
||||
import PinTemplate from "../template/pin/PinTemplate.js"
|
||||
import RealPinTemplate from "../template/pin/RealPinTemplate.js"
|
||||
import ReferencePinTemplate from "../template/pin/ReferencePinTemplate.js"
|
||||
import RotatorPinTemplate from "../template/pin/RotatorPinTemplate.js"
|
||||
import StringPinTemplate from "../template/pin/StringPinTemplate.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Vector2DPinTemplate from "../template/pin/Vector2DPinTemplate.js"
|
||||
import VectorPinTemplate from "../template/pin/VectorPinTemplate.js"
|
||||
import ElementFactory from "./ElementFactory.js"
|
||||
import IElement from "./IElement.js"
|
||||
|
||||
/**
|
||||
* @template {TerminalAttribute} T
|
||||
@@ -202,6 +202,9 @@ export default class PinElement extends IElement {
|
||||
setDefaultValue(value) {
|
||||
this.entity.DefaultValue = value
|
||||
this.defaultValue = value
|
||||
if (this.entity.recomputesNodeTitleOnChange) {
|
||||
this.nodeElement?.computeNodeDisplayName()
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {IElement[]} nodesWhitelist */
|
||||
@@ -237,6 +240,9 @@ export default class PinElement extends IElement {
|
||||
if (this.entity.linkTo(targetPinElement.getNodeElement().getNodeName(), targetPinElement.entity)) {
|
||||
this.isLinked = this.entity.isLinked()
|
||||
this.nodeElement?.template.linksChanged()
|
||||
if (this.entity.recomputesNodeTitleOnChange) {
|
||||
this.nodeElement?.computeNodeDisplayName()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +254,9 @@ export default class PinElement extends IElement {
|
||||
if (removeLink) {
|
||||
this.blueprint.getLink(this, targetPinElement)?.remove() // Might be called after the link is removed
|
||||
}
|
||||
if (this.entity.recomputesNodeTitleOnChange) {
|
||||
this.nodeElement?.computeNodeDisplayName()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
114
js/entity/AttributeInfo.js
Normal file
114
js/entity/AttributeInfo.js
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {{
|
||||
* type?: AttributeTypeDescription,
|
||||
* default?: T,
|
||||
* nullable?: Boolean,
|
||||
* ignored?: Boolean,
|
||||
* serialized?: Boolean,
|
||||
* expected?: Boolean,
|
||||
* inlined?: Boolean,
|
||||
* quoted?: Boolean,
|
||||
* silent?: Boolean,
|
||||
* predicate?: (value: T) => Boolean,
|
||||
* }} AttributeInfoSource
|
||||
*/
|
||||
|
||||
/** @template T */
|
||||
export default class AttributeInfo {
|
||||
|
||||
/** @typedef {keyof AttributeInfo<number>} AttributeKey */
|
||||
|
||||
static #default = {
|
||||
nullable: false,
|
||||
ignored: false, // Never serialize or deserialize
|
||||
serialized: false, // Value is written and read as string
|
||||
expected: false, // Must be there
|
||||
inlined: false, // The key is a subobject or array and printed as inlined (A.B=123, A(0)=123)
|
||||
quoted: false, // Key is serialized with quotes
|
||||
silent: false, // Do not serialize if default
|
||||
}
|
||||
|
||||
/** @param {AttributeInfoSource<T>} source */
|
||||
constructor(source) {
|
||||
this.type = source.type ?? source.default?.constructor
|
||||
this.default = source.default
|
||||
this.nullable = source.nullable ?? source.default === null
|
||||
this.ignored = source.ignored
|
||||
this.serialized = source.serialized
|
||||
this.expected = source.expected
|
||||
this.inlined = source.inlined
|
||||
this.quoted = source.quoted
|
||||
this.silent = source.silent
|
||||
this.predicate = source.predicate
|
||||
if (this.type === Array && this.default instanceof Array && this.default.length > 0) {
|
||||
this.type = this.default
|
||||
.map(v => v.constructor)
|
||||
.reduce((acc, cur) => acc.includes(cur) ? acc : (acc.push(cur), acc), [])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {AttributeTypeDescription} D
|
||||
* @param {D} type
|
||||
* @returns {AttributeInfo<DescribedType<type>>}
|
||||
*/
|
||||
static createType(type) {
|
||||
return new AttributeInfo({ type })
|
||||
}
|
||||
|
||||
/**
|
||||
* @template V
|
||||
* @param {V} value
|
||||
*/
|
||||
static createValue(value) {
|
||||
return new AttributeInfo({ default: value })
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {IEntity | Object} source
|
||||
* @param {String} attribute
|
||||
* @param {AttributeKey} key
|
||||
*/
|
||||
static hasAttribute(source, attribute, key, type = /** @type {EntityConstructor} */(source.constructor)) {
|
||||
const entity = /** @type {IEntity} */(source)
|
||||
const result = entity.attributes[attribute]?.[key]
|
||||
return /** @type {result} */(
|
||||
result
|
||||
?? type?.attributes?.[attribute]?.[key]
|
||||
?? AttributeInfo.#default[key]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {IEntity | Object} S
|
||||
* @template {EntityConstructor} C
|
||||
* @template {keyof C["attributes"]} A
|
||||
* @template {keyof C["attributes"][attribute]} K
|
||||
* @param {S} source
|
||||
* @param {A} attribute
|
||||
* @param {K} key
|
||||
* @param {C} type
|
||||
* @returns {C["attributes"][attribute][key]}
|
||||
*/
|
||||
static getAttribute(source, attribute, key, type = /** @type {C} */(source.constructor)) {
|
||||
let result = source["attributes"]?.[attribute]?.[key]
|
||||
// Remember null is a valid asignment value for some attributes
|
||||
if (result !== undefined) {
|
||||
return result
|
||||
}
|
||||
result = /** @type {C["attributes"]} */(type?.attributes)?.[attribute]?.[key]
|
||||
if (result !== undefined) {
|
||||
return result
|
||||
}
|
||||
result = /** @type {C["attributes"][attribute]} */(AttributeInfo.#default)[key]
|
||||
if (result !== undefined) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {AttributeKey} key */
|
||||
get(key) {
|
||||
return this[key] ?? AttributeInfo.#default[key]
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class Base64ObjectsEncoded extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
type: String,
|
||||
},
|
||||
objects: {
|
||||
value: AttributeInfo.createType(String),
|
||||
objects: new AttributeInfo({
|
||||
ignored: true,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import IntegerEntity from "./IntegerEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IntegerEntity from "./IntegerEntity.js"
|
||||
|
||||
export default class ByteEntity extends IntegerEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
value: new AttributeInfo({
|
||||
...super.attributes.value,
|
||||
predicate: v => v % 1 == 0 && v >= 0 && v < 1 << 8,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class ColorChannelEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
default: 0,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
value: AttributeInfo.createValue(0),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import EnumEntity from "./EnumEntity.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import EnumEntity from "./EnumEntity.js"
|
||||
|
||||
export default class EnumDisplayValueEntity extends EnumEntity {
|
||||
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import InvariantTextEntity from "./InvariantTextEntity.js"
|
||||
import LocalizedTextEntity from "./LocalizedTextEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Union from "./Union.js"
|
||||
|
||||
export default class FormatTextEntity extends IEntity {
|
||||
|
||||
static lookbehind = new Union("LOCGEN_FORMAT_NAMED", "LOCGEN_FORMAT_ORDERED")
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
value: new AttributeInfo({
|
||||
type: [new Union(String, LocalizedTextEntity, InvariantTextEntity, FormatTextEntity)],
|
||||
default: [],
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
lookbehind: /** @type {AttributeInfo<Union<String[]>>} */(new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: new Union("LOCGEN_FORMAT_NAMED", "LOCGEN_FORMAT_ORDERED"),
|
||||
})),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
@@ -24,7 +25,7 @@ export default class FormatTextEntity extends IEntity {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(
|
||||
// Resulting regex: /(LOCGEN_FORMAT_NAMED|LOCGEN_FORMAT_ORDERED)\s*/
|
||||
new RegExp(`(${this.lookbehind.values.reduce((acc, cur) => acc + "|" + cur)})\\s*`),
|
||||
new RegExp(`(${this.attributes.lookbehind.default.values.reduce((acc, cur) => acc + "|" + cur)})\\s*`),
|
||||
1
|
||||
),
|
||||
Grammar.grammarFor(this.attributes.value)
|
||||
@@ -32,8 +33,8 @@ export default class FormatTextEntity extends IEntity {
|
||||
.map(([lookbehind, values]) => {
|
||||
const result = new this({
|
||||
value: values,
|
||||
lookbehind,
|
||||
})
|
||||
result.lookbehind = lookbehind
|
||||
return result
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
|
||||
@@ -7,18 +8,9 @@ export default class FunctionReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
MemberParent: {
|
||||
type: ObjectReferenceEntity,
|
||||
},
|
||||
MemberName: {
|
||||
type: String,
|
||||
},
|
||||
MemberGuid: {
|
||||
type: GuidEntity,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
MemberParent: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MemberName: AttributeInfo.createType(String),
|
||||
MemberGuid: AttributeInfo.createType(GuidEntity),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
var crypto
|
||||
if (typeof window === "undefined") {
|
||||
import("crypto").then(mod => crypto = mod.default).catch()
|
||||
} else {
|
||||
crypto = window.crypto
|
||||
}
|
||||
|
||||
export default class GuidEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
default: "",
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
value: AttributeInfo.createValue(""),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,121 +1,85 @@
|
||||
import ComputedType from "./ComputedType.js"
|
||||
import Configuration from "../Configuration.js"
|
||||
import MirroredEntity from "./MirroredEntity.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Serializable from "../serialization/Serializable.js"
|
||||
import SerializerFactory from "../serialization/SerializerFactory.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import ComputedType from "./ComputedType.js"
|
||||
import MirroredEntity from "./MirroredEntity.js"
|
||||
import Union from "./Union.js"
|
||||
import Utility from "../Utility.js"
|
||||
|
||||
/** @abstract */
|
||||
export default class IEntity extends Serializable {
|
||||
|
||||
/** @type {String | Union<String[]>} */
|
||||
static lookbehind = ""
|
||||
/** @type {AttributeDeclarations} */
|
||||
static attributes = {
|
||||
lookbehind: {
|
||||
attributes: new AttributeInfo({
|
||||
ignored: true,
|
||||
}
|
||||
}
|
||||
static defaultAttribute = {
|
||||
nullable: false,
|
||||
ignored: false,
|
||||
serialized: false, // Value is written and read as string
|
||||
expected: false, // Must be there
|
||||
inlined: false, // The key is a subobject or array and printed as inlined (A.B=123, A(0)=123)
|
||||
quoted: false, // Key is serialized with quotes
|
||||
}),
|
||||
lookbehind: new AttributeInfo({
|
||||
default: /** @type {String | Union<String[]>} */(""),
|
||||
ignored: true,
|
||||
}),
|
||||
}
|
||||
|
||||
constructor(values = {}, suppressWarns = false) {
|
||||
super()
|
||||
/** @type {String} */ this.lookbehind
|
||||
const Self = /** @type {typeof IEntity} */(this.constructor)
|
||||
let attributes = Self.attributes
|
||||
if (values.attributes) {
|
||||
attributes = { ...Self.attributes }
|
||||
Utility.mergeArrays(Object.keys(values.attributes), Object.keys(attributes))
|
||||
.forEach(k => {
|
||||
attributes[k] = {
|
||||
...IEntity.defaultAttribute,
|
||||
...attributes[k],
|
||||
...values.attributes[k],
|
||||
}
|
||||
if (!attributes[k].type) {
|
||||
attributes[k].type = values[k] instanceof Array
|
||||
? [Utility.getType(values[k][0])]
|
||||
: Utility.getType(values[k])
|
||||
}
|
||||
})
|
||||
IEntity.defineAttributes(this, attributes)
|
||||
}
|
||||
/** @type {AttributeDeclarations?} */ this.attributes
|
||||
const valuesNames = Object.keys(values)
|
||||
const attributesNames = Object.keys(attributes)
|
||||
const allAttributesNames = Utility.mergeArrays(valuesNames, attributesNames)
|
||||
if (valuesNames.includes("lookbehind")) {
|
||||
this.lookbehind = undefined // To keep it first
|
||||
}
|
||||
for (const attributeName of allAttributesNames) {
|
||||
if (attributeName == "attributes") {
|
||||
// Ignore this special attribute describing all the attributes
|
||||
continue
|
||||
}
|
||||
let value = values[attributeName]
|
||||
let attribute = attributes[attributeName]
|
||||
|
||||
if (!suppressWarns && value !== undefined) {
|
||||
if (
|
||||
!(attributeName in attributes)
|
||||
&& !attributeName.startsWith(Configuration.subObjectAttributeNamePrefix)
|
||||
) {
|
||||
/** @type {String} */ this.lookbehind
|
||||
const valuesKeys = Object.keys(values)
|
||||
const attributesKeys = values.attributes
|
||||
? Utility.mergeArrays(Object.keys(values.attributes), Object.keys(Self.attributes))
|
||||
: Object.keys(Self.attributes)
|
||||
const allAttributesKeys = Utility.mergeArrays(valuesKeys, attributesKeys)
|
||||
for (const key of allAttributesKeys) {
|
||||
let value = values[key]
|
||||
if (!suppressWarns && !(key in values)) {
|
||||
if (!(key in Self.attributes) && !key.startsWith(Configuration.subObjectAttributeNamePrefix)) {
|
||||
const typeName = value instanceof Array ? `[${value[0]?.constructor.name}]` : value.constructor.name
|
||||
console.warn(
|
||||
`UEBlueprint: Attribute ${attributeName} (of type ${typeName}) in the serialized data is not `
|
||||
+ `defined in ${Self.name}.attributes`
|
||||
`UEBlueprint: Attribute ${key} (of type ${typeName}) in the serialized data is not defined in ${Self.name}.attributes`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (!attribute) {
|
||||
if (!(key in Self.attributes)) {
|
||||
// Remember attributeName can come from the values and be not defined in the attributes.
|
||||
// In that case just assign it and skip the rest.
|
||||
this[attributeName] = value
|
||||
this[key] = value
|
||||
continue
|
||||
}
|
||||
|
||||
const assignAttribute = !attribute.predicate
|
||||
? v => this[attributeName] = v
|
||||
Self.attributes.lookbehind
|
||||
const predicate = AttributeInfo.getAttribute(values, key, "predicate", Self)
|
||||
const assignAttribute = !predicate
|
||||
? v => this[key] = v
|
||||
: v => {
|
||||
Object.defineProperties(this, {
|
||||
["#" + attributeName]: {
|
||||
["#" + key]: {
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
},
|
||||
[attributeName]: {
|
||||
[key]: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this["#" + attributeName]
|
||||
return this["#" + key]
|
||||
},
|
||||
set(v) {
|
||||
if (!attribute.predicate?.(v)) {
|
||||
if (!predicate(v)) {
|
||||
console.warn(
|
||||
`UEBlueprint: Tried to assign attribute ${attributeName} to ${Self.name} not `
|
||||
+ "satisfying the predicate"
|
||||
`UEBlueprint: Tried to assign attribute ${key} to ${Self.name} not satisfying the predicate`
|
||||
)
|
||||
return
|
||||
}
|
||||
this["#" + attributeName] = v
|
||||
this["#" + key] = v
|
||||
}
|
||||
},
|
||||
})
|
||||
this[attributeName] = v
|
||||
this[key] = v
|
||||
}
|
||||
|
||||
let defaultValue = attribute.default
|
||||
let defaultValue = AttributeInfo.getAttribute(values, key, "default", Self)
|
||||
if (defaultValue instanceof Function) {
|
||||
defaultValue = defaultValue(this)
|
||||
}
|
||||
let defaultType = attribute.type
|
||||
let defaultType = AttributeInfo.getAttribute(values, key, "type", Self)
|
||||
if (defaultType instanceof ComputedType) {
|
||||
defaultType = defaultType.compute(this)
|
||||
}
|
||||
@@ -128,16 +92,24 @@ export default class IEntity extends Serializable {
|
||||
|
||||
if (value !== undefined) {
|
||||
// Remember value can still be null
|
||||
if (value?.constructor === String && attribute.serialized && defaultType !== String) {
|
||||
value = SerializerFactory
|
||||
// @ts-expect-error
|
||||
.getSerializer(defaultType)
|
||||
.read(/** @type {String} */(value))
|
||||
if (
|
||||
value?.constructor === String
|
||||
&& AttributeInfo.getAttribute(values, key, "serialized", Self)
|
||||
&& defaultType !== String
|
||||
) {
|
||||
try {
|
||||
value = SerializerFactory
|
||||
.getSerializer(defaultType)
|
||||
.read(/** @type {String} */(value))
|
||||
} catch (e) {
|
||||
assignAttribute(value)
|
||||
continue
|
||||
}
|
||||
}
|
||||
assignAttribute(Utility.sanitize(value, /** @type {AttributeConstructor<Attribute>} */(defaultType)))
|
||||
continue // We have a value, need nothing more
|
||||
}
|
||||
if (Object.hasOwn(attribute, "default")) { // Accept also explicit undefined
|
||||
if (defaultValue !== undefined) {
|
||||
assignAttribute(defaultValue)
|
||||
}
|
||||
}
|
||||
@@ -166,31 +138,6 @@ export default class IEntity extends Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {AttributeDeclarations} attributes */
|
||||
static cleanupAttributes(attributes, prefix = "") {
|
||||
for (const attributeName in attributes) {
|
||||
attributes[attributeName] = {
|
||||
...IEntity.defaultAttribute,
|
||||
...attributes[attributeName],
|
||||
}
|
||||
const attribute = /** @type {AttributeInformation} */(attributes[attributeName])
|
||||
if (attribute.type === undefined && !(attribute.default instanceof Function)) {
|
||||
attribute.type = attribute.default instanceof Array
|
||||
? [Utility.getType(attribute.default[0])]
|
||||
: Utility.getType(attribute.default)
|
||||
}
|
||||
if (!attribute.ignored && attribute.default === undefined && attribute.type === undefined) {
|
||||
throw new Error(
|
||||
`UEBlueprint: Expected either "type" or "value" property in ${this.name} attribute ${prefix}`
|
||||
+ attributeName
|
||||
)
|
||||
}
|
||||
if (attribute.default === null) {
|
||||
attribute.nullable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {new (...args: any) => any} C
|
||||
* @param {C} type
|
||||
@@ -224,7 +171,7 @@ export default class IEntity extends Serializable {
|
||||
}
|
||||
|
||||
getLookbehind() {
|
||||
let lookbehind = this.lookbehind ?? /** @type {EntityConstructor} */(this.constructor).lookbehind
|
||||
let lookbehind = this.lookbehind ?? AttributeInfo.getAttribute(this, "lookbehind", "default")
|
||||
lookbehind = lookbehind instanceof Union ? lookbehind.values[0] : lookbehind
|
||||
return lookbehind
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class IdentifierEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
default: "",
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
value: AttributeInfo.createValue(""),
|
||||
}
|
||||
static attributeConverter = {
|
||||
fromAttribute: (value, type) => new IdentifierEntity(value),
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class Integer64Entity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
value: new AttributeInfo({
|
||||
default: 0n,
|
||||
predicate: v => v >= -(1n << 63n) && v < 1n << 63n,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class IntegerEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
value: new AttributeInfo({
|
||||
default: 0,
|
||||
predicate: v => v % 1 == 0 && v > 1 << 31 && v < -(1 << 31),
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
@@ -19,7 +17,7 @@ export default class IntegerEntity extends IEntity {
|
||||
return Parsernostrum.numberInteger.map(v => new this(v))
|
||||
}
|
||||
|
||||
/** @param {Number | AttributeInformation} value */
|
||||
/** @param {Number | AttributeInfo<IntegerEntity>} value */
|
||||
constructor(value = 0) {
|
||||
if (value === -0) {
|
||||
value = 0
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class InvariantTextEntity extends IEntity {
|
||||
|
||||
static lookbehind = "INVTEXT"
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
default: "",
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
value: AttributeInfo.createValue(""),
|
||||
lookbehind: new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: "INVTEXT",
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.alt(
|
||||
Parsernostrum.seq(
|
||||
Parsernostrum.reg(new RegExp(`${this.lookbehind}\\s*\\(`)),
|
||||
Parsernostrum.reg(new RegExp(`${this.attributes.lookbehind.default}\\s*\\(`)),
|
||||
Grammar.grammarFor(this.attributes.value),
|
||||
Parsernostrum.reg(/\s*\)/)
|
||||
)
|
||||
.map(([_0, value, _2]) => value),
|
||||
Parsernostrum.reg(new RegExp(this.lookbehind)) // InvariantTextEntity can not have arguments
|
||||
Parsernostrum.reg(new RegExp(this.attributes.lookbehind.default)) // InvariantTextEntity can not have arguments
|
||||
.map(() => "")
|
||||
).map(value => new this(value))
|
||||
}
|
||||
|
||||
@@ -1,33 +1,19 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IdentifierEntity from "./IdentifierEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import IdentifierEntity from "./IdentifierEntity.js"
|
||||
|
||||
export default class KeyBindingEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
ActionName: {
|
||||
default: "",
|
||||
},
|
||||
bShift: {
|
||||
default: false,
|
||||
},
|
||||
bCtrl: {
|
||||
default: false,
|
||||
},
|
||||
bAlt: {
|
||||
default: false,
|
||||
},
|
||||
bCmd: {
|
||||
default: false,
|
||||
},
|
||||
Key: {
|
||||
type: IdentifierEntity,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
ActionName: AttributeInfo.createValue(""),
|
||||
bShift: AttributeInfo.createValue(false),
|
||||
bCtrl: AttributeInfo.createValue(false),
|
||||
bAlt: AttributeInfo.createValue(false),
|
||||
bCmd: AttributeInfo.createValue(false),
|
||||
Key: AttributeInfo.createType(IdentifierEntity),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,51 +1,49 @@
|
||||
import { css } from "lit"
|
||||
import ColorChannelEntity from "./ColorChannelEntity.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Utility from "../Utility.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import ColorChannelEntity from "./ColorChannelEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class LinearColorEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
R: {
|
||||
R: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
expected: true,
|
||||
},
|
||||
G: {
|
||||
}),
|
||||
G: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
expected: true,
|
||||
},
|
||||
B: {
|
||||
}),
|
||||
B: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
expected: true,
|
||||
},
|
||||
A: {
|
||||
}),
|
||||
A: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(1),
|
||||
},
|
||||
H: {
|
||||
}),
|
||||
H: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
ignored: true,
|
||||
},
|
||||
S: {
|
||||
}),
|
||||
S: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
ignored: true,
|
||||
},
|
||||
V: {
|
||||
}),
|
||||
V: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
ignored: true,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,31 +1,26 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Utility from "../Utility.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class LocalizedTextEntity extends IEntity {
|
||||
|
||||
static lookbehind = "NSLOCTEXT"
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
namespace: {
|
||||
default: "",
|
||||
},
|
||||
key: {
|
||||
default: "",
|
||||
},
|
||||
value: {
|
||||
default: "",
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
namespace: AttributeInfo.createValue(""),
|
||||
key: AttributeInfo.createValue(""),
|
||||
value: AttributeInfo.createValue(""),
|
||||
lookbehind: new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: "NSLOCTEXT",
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.regArray(new RegExp(
|
||||
String.raw`${this.lookbehind}\s*\(`
|
||||
String.raw`${this.attributes.lookbehind.default}\s*\(`
|
||||
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*,`
|
||||
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*,`
|
||||
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*`
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
|
||||
@@ -7,21 +8,18 @@ export default class MacroGraphReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
MacroGraph: {
|
||||
MacroGraph: new AttributeInfo({
|
||||
type: ObjectReferenceEntity,
|
||||
default: () => new ObjectReferenceEntity(),
|
||||
},
|
||||
GraphBlueprint: {
|
||||
}),
|
||||
GraphBlueprint: new AttributeInfo({
|
||||
type: ObjectReferenceEntity,
|
||||
default: () => new ObjectReferenceEntity(),
|
||||
},
|
||||
GraphGuid: {
|
||||
}),
|
||||
GraphGuid: new AttributeInfo({
|
||||
type: GuidEntity,
|
||||
default: () => new GuidEntity(),
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
|
||||
/** @template {Attribute} T */
|
||||
export default class MirroredEntity {
|
||||
|
||||
static attributes = {
|
||||
type: {
|
||||
type: new AttributeInfo({
|
||||
ignored: true,
|
||||
},
|
||||
getter: {
|
||||
}),
|
||||
getter: new AttributeInfo({
|
||||
ignored: true,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Configuration from "../Configuration.js"
|
||||
import FunctionReferenceEntity from "./FunctionReferenceEntity.js"
|
||||
import SVGIcon from "../SVGIcon.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import FunctionReferenceEntity from "./FunctionReferenceEntity.js"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IdentifierEntity from "./IdentifierEntity.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 Parsernostrum from "parsernostrum"
|
||||
import PinEntity from "./PinEntity.js"
|
||||
import SVGIcon from "../SVGIcon.js"
|
||||
import SymbolEntity from "./SymbolEntity.js"
|
||||
import Union from "./Union.js"
|
||||
import UnknownPinEntity from "./UnknownPinEntity.js"
|
||||
import Utility from "../Utility.js"
|
||||
import VariableReferenceEntity from "./VariableReferenceEntity.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
|
||||
export default class ObjectEntity extends IEntity {
|
||||
|
||||
@@ -50,112 +51,123 @@ export default class ObjectEntity extends IEntity {
|
||||
}
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
AdvancedPinDisplay: { type: IdentifierEntity },
|
||||
Archetype: { type: ObjectReferenceEntity },
|
||||
AxisKey: { type: SymbolEntity },
|
||||
bAlt: { type: Boolean },
|
||||
bCanRenameNode: { type: Boolean },
|
||||
bColorCommentBubble: { type: Boolean },
|
||||
bCommand: { type: Boolean },
|
||||
bCommentBubblePinned: { type: Boolean },
|
||||
bCommentBubbleVisible_InDetailsPanel: { type: Boolean },
|
||||
bCommentBubbleVisible: { type: Boolean },
|
||||
bConsumeInput: { type: Boolean },
|
||||
bControl: { type: Boolean },
|
||||
bExecuteWhenPaused: { type: Boolean },
|
||||
bExposeToLibrary: { type: Boolean },
|
||||
bInternalEvent: { type: Boolean },
|
||||
bIsCaseSensitive: { type: Boolean },
|
||||
bIsConstFunc: { type: Boolean },
|
||||
bIsPureFunc: { type: Boolean },
|
||||
BlueprintElementInstance: { type: ObjectReferenceEntity },
|
||||
BlueprintElementType: { type: ObjectReferenceEntity },
|
||||
bOverrideFunction: { type: Boolean },
|
||||
bOverrideParentBinding: { type: Boolean },
|
||||
bShift: { type: Boolean },
|
||||
Class: { type: ObjectReferenceEntity },
|
||||
CommentColor: { type: LinearColorEntity },
|
||||
ComponentPropertyName: { type: String },
|
||||
CustomFunctionName: { type: String },
|
||||
CustomProperties: { type: [new Union(PinEntity, UnknownPinEntity)] },
|
||||
DelegateOwnerClass: { type: ObjectReferenceEntity },
|
||||
DelegatePropertyName: { type: String },
|
||||
DelegateReference: { type: VariableReferenceEntity },
|
||||
EnabledState: { type: IdentifierEntity },
|
||||
Enum: { type: ObjectReferenceEntity },
|
||||
EnumEntries: {
|
||||
R: new AttributeInfo({
|
||||
default: false,
|
||||
silent: true,
|
||||
}),
|
||||
G: new AttributeInfo({
|
||||
default: false,
|
||||
silent: true,
|
||||
}),
|
||||
B: new AttributeInfo({
|
||||
default: false,
|
||||
silent: true,
|
||||
}),
|
||||
A: new AttributeInfo({
|
||||
default: false,
|
||||
silent: true,
|
||||
}),
|
||||
AdvancedPinDisplay: AttributeInfo.createType(IdentifierEntity),
|
||||
Archetype: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
AxisKey: AttributeInfo.createType(SymbolEntity),
|
||||
bAlt: AttributeInfo.createType(Boolean),
|
||||
bCanRenameNode: AttributeInfo.createType(Boolean),
|
||||
bColorCommentBubble: AttributeInfo.createType(Boolean),
|
||||
bCommand: AttributeInfo.createType(Boolean),
|
||||
bCommentBubblePinned: AttributeInfo.createType(Boolean),
|
||||
bCommentBubbleVisible_InDetailsPanel: AttributeInfo.createType(Boolean),
|
||||
bCommentBubbleVisible: AttributeInfo.createType(Boolean),
|
||||
bConsumeInput: AttributeInfo.createType(Boolean),
|
||||
bControl: AttributeInfo.createType(Boolean),
|
||||
bExecuteWhenPaused: AttributeInfo.createType(Boolean),
|
||||
bExposeToLibrary: AttributeInfo.createType(Boolean),
|
||||
bInternalEvent: AttributeInfo.createType(Boolean),
|
||||
bIsCaseSensitive: AttributeInfo.createType(Boolean),
|
||||
bIsConstFunc: AttributeInfo.createType(Boolean),
|
||||
bIsPureFunc: AttributeInfo.createType(Boolean),
|
||||
BlueprintElementInstance: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
BlueprintElementType: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
bOverrideFunction: AttributeInfo.createType(Boolean),
|
||||
bOverrideParentBinding: AttributeInfo.createType(Boolean),
|
||||
bShift: AttributeInfo.createType(Boolean),
|
||||
Class: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
CommentColor: AttributeInfo.createType(LinearColorEntity),
|
||||
ComponentPropertyName: AttributeInfo.createType(String),
|
||||
CustomFunctionName: AttributeInfo.createType(String),
|
||||
CustomProperties: AttributeInfo.createType([new Union(PinEntity, UnknownPinEntity)]),
|
||||
DelegateOwnerClass: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
DelegatePropertyName: AttributeInfo.createType(String),
|
||||
DelegateReference: AttributeInfo.createType(VariableReferenceEntity),
|
||||
EnabledState: AttributeInfo.createType(IdentifierEntity),
|
||||
Enum: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
EnumEntries: new AttributeInfo({
|
||||
type: [String],
|
||||
inlined: true,
|
||||
},
|
||||
ErrorMsg: { type: String },
|
||||
ErrorType: { type: IntegerEntity },
|
||||
EventReference: { type: FunctionReferenceEntity },
|
||||
ExportPath: { type: ObjectReferenceEntity },
|
||||
FunctionReference: { type: FunctionReferenceEntity },
|
||||
G: { type: Number },
|
||||
Graph: { type: ObjectReferenceEntity },
|
||||
HiGenGridSize: { type: SymbolEntity },
|
||||
InputAxisKey: { type: SymbolEntity },
|
||||
InputKey: { type: SymbolEntity },
|
||||
InputName: { type: String },
|
||||
InputPins: {
|
||||
}),
|
||||
ErrorMsg: AttributeInfo.createType(String),
|
||||
ErrorType: AttributeInfo.createType(IntegerEntity),
|
||||
EventReference: AttributeInfo.createType(FunctionReferenceEntity),
|
||||
ExportPath: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
FunctionReference: AttributeInfo.createType(FunctionReferenceEntity),
|
||||
Graph: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
HiGenGridSize: AttributeInfo.createType(SymbolEntity),
|
||||
InputAxisKey: AttributeInfo.createType(SymbolEntity),
|
||||
InputKey: AttributeInfo.createType(SymbolEntity),
|
||||
InputName: AttributeInfo.createType(String),
|
||||
InputPins: new AttributeInfo({
|
||||
type: [ObjectReferenceEntity],
|
||||
inlined: true,
|
||||
},
|
||||
InputType: { type: SymbolEntity },
|
||||
MacroGraphReference: { type: MacroGraphReferenceEntity },
|
||||
MaterialExpression: { type: ObjectReferenceEntity },
|
||||
MaterialExpressionComment: { type: ObjectReferenceEntity },
|
||||
MaterialExpressionEditorX: { type: new MirroredEntity(IntegerEntity) },
|
||||
MaterialExpressionEditorY: { type: new MirroredEntity(IntegerEntity) },
|
||||
MaterialFunction: { type: ObjectReferenceEntity },
|
||||
MoveMode: { type: SymbolEntity },
|
||||
Name: { type: String },
|
||||
Node: { type: new MirroredEntity(ObjectReferenceEntity) },
|
||||
NodeComment: { type: String },
|
||||
NodeGuid: { type: GuidEntity },
|
||||
NodeHeight: { type: IntegerEntity },
|
||||
NodePosX: { type: IntegerEntity },
|
||||
NodePosY: { type: IntegerEntity },
|
||||
NodeTitle: { type: String },
|
||||
NodeTitleColor: { type: LinearColorEntity },
|
||||
NodeWidth: { type: IntegerEntity },
|
||||
NumAdditionalInputs: { type: Number },
|
||||
ObjectRef: { type: ObjectReferenceEntity },
|
||||
Operation: { type: SymbolEntity },
|
||||
OutputPins: {
|
||||
}),
|
||||
InputType: AttributeInfo.createType(SymbolEntity),
|
||||
MacroGraphReference: AttributeInfo.createType(MacroGraphReferenceEntity),
|
||||
MaterialExpression: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MaterialExpressionComment: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MaterialExpressionEditorX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
MaterialExpressionEditorY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
MaterialFunction: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MoveMode: AttributeInfo.createType(SymbolEntity),
|
||||
Name: AttributeInfo.createType(String),
|
||||
Node: AttributeInfo.createType(new MirroredEntity(ObjectReferenceEntity)),
|
||||
NodeComment: AttributeInfo.createType(String),
|
||||
NodeGuid: AttributeInfo.createType(GuidEntity),
|
||||
NodeHeight: AttributeInfo.createType(IntegerEntity),
|
||||
NodePosX: AttributeInfo.createType(IntegerEntity),
|
||||
NodePosY: AttributeInfo.createType(IntegerEntity),
|
||||
NodeTitle: AttributeInfo.createType(String),
|
||||
NodeTitleColor: AttributeInfo.createType(LinearColorEntity),
|
||||
NodeWidth: AttributeInfo.createType(IntegerEntity),
|
||||
NumAdditionalInputs: AttributeInfo.createType(Number),
|
||||
ObjectRef: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
Operation: AttributeInfo.createType(SymbolEntity),
|
||||
OutputPins: new AttributeInfo({
|
||||
type: [ObjectReferenceEntity],
|
||||
inlined: true,
|
||||
},
|
||||
PCGNode: { type: ObjectReferenceEntity },
|
||||
PinNames: {
|
||||
}),
|
||||
PCGNode: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
PinNames: new AttributeInfo({
|
||||
type: [String],
|
||||
inlined: true,
|
||||
},
|
||||
PinTags: {
|
||||
}),
|
||||
PinTags: new AttributeInfo({
|
||||
type: [null],
|
||||
inlined: true,
|
||||
},
|
||||
PositionX: { type: new MirroredEntity(IntegerEntity) },
|
||||
PositionY: { type: new MirroredEntity(IntegerEntity) },
|
||||
ProxyClass: { type: ObjectReferenceEntity },
|
||||
ProxyFactoryClass: { type: ObjectReferenceEntity },
|
||||
ProxyFactoryFunctionName: { type: String },
|
||||
R: { type: Number },
|
||||
SelfContextInfo: { type: SymbolEntity },
|
||||
SettingsInterface: { type: ObjectReferenceEntity },
|
||||
SizeX: { type: new MirroredEntity(IntegerEntity) },
|
||||
SizeY: { type: new MirroredEntity(IntegerEntity) },
|
||||
StructType: { type: ObjectReferenceEntity },
|
||||
SubgraphInstance: { type: String },
|
||||
TargetType: { type: ObjectReferenceEntity },
|
||||
Text: { type: new MirroredEntity(String) },
|
||||
TimelineGuid: { type: GuidEntity },
|
||||
TimelineName: { type: String },
|
||||
VariableReference: { type: VariableReferenceEntity },
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
PositionX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
PositionY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
ProxyClass: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
ProxyFactoryClass: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
ProxyFactoryFunctionName: AttributeInfo.createType(String),
|
||||
SelfContextInfo: AttributeInfo.createType(SymbolEntity),
|
||||
SettingsInterface: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
SizeX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
SizeY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
StructType: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
SubgraphInstance: AttributeInfo.createType(String),
|
||||
TargetType: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
Text: AttributeInfo.createType(new MirroredEntity(String)),
|
||||
TimelineGuid: AttributeInfo.createType(GuidEntity),
|
||||
TimelineName: AttributeInfo.createType(String),
|
||||
VariableReference: AttributeInfo.createType(VariableReferenceEntity),
|
||||
}
|
||||
static nameRegex = /^(\w+?)(?:_(\d+))?$/
|
||||
static sequencerScriptingNameRegex = /\/Script\/SequencerScripting\.MovieSceneScripting(.+)Channel/
|
||||
@@ -287,33 +299,21 @@ export default class ObjectEntity extends IEntity {
|
||||
}
|
||||
}
|
||||
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.bAlt
|
||||
/** @type {Boolean} */ this.bCanRenameNode
|
||||
/** @type {Boolean} */ this.bColorCommentBubble
|
||||
/** @type {Boolean} */ this.bCommand
|
||||
/** @type {Boolean} */ this.bCommentBubblePinned
|
||||
/** @type {Boolean} */ this.bCommentBubbleVisible
|
||||
/** @type {Boolean} */ this.bCommentBubbleVisible_InDetailsPanel
|
||||
/** @type {Boolean} */ this.bConsumeInput
|
||||
/** @type {Boolean} */ this.bControl
|
||||
/** @type {Boolean} */ this.bExecuteWhenPaused
|
||||
/** @type {Boolean} */ this.bExposeToLibrary
|
||||
/** @type {Boolean} */ this.bInternalEvent
|
||||
/** @type {Boolean} */ this.bIsCaseSensitive
|
||||
/** @type {Boolean} */ this.bIsConstFunc
|
||||
/** @type {Boolean} */ this.bIsPureFunc
|
||||
/** @type {Boolean} */ this.bOverrideFunction
|
||||
/** @type {Boolean} */ this.bOverrideParentBinding
|
||||
/** @type {Boolean} */ this.bShift
|
||||
/** @type {FunctionReferenceEntity} */ this.ComponentPropertyName
|
||||
/** @type {FunctionReferenceEntity} */ this.EventReference
|
||||
/** @type {FunctionReferenceEntity} */ this.FunctionReference
|
||||
/** @type {GuidEntity} */ this.NodeGuid
|
||||
/** @type {GuidEntity} */ this.TimelineGuid
|
||||
/** @type {IdentifierEntity} */ this.AdvancedPinDisplay
|
||||
/** @type {IdentifierEntity} */ this.EnabledState
|
||||
/** @type {IntegerEntity} */ this.ErrorType
|
||||
/** @type {IntegerEntity} */ this.NodeHeight
|
||||
/** @type {IntegerEntity} */ this.NodePosX
|
||||
/** @type {IntegerEntity} */ this.NodePosY
|
||||
@@ -330,16 +330,13 @@ export default class ObjectEntity extends IEntity {
|
||||
/** @type {MirroredEntity<IntegerEntity>} */ this.PositionY
|
||||
/** @type {MirroredEntity<ObjectReferenceEntity>} */ this.Node
|
||||
/** @type {null[]} */ this.PinTags
|
||||
/** @type {Number} */ this.G
|
||||
/** @type {Number} */ this.NumAdditionalInputs
|
||||
/** @type {Number} */ this.R
|
||||
/** @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.DelegateOwnerClass
|
||||
/** @type {ObjectReferenceEntity} */ this.Enum
|
||||
/** @type {ObjectReferenceEntity} */ this.ExportPath
|
||||
/** @type {ObjectReferenceEntity} */ this.Graph
|
||||
@@ -348,8 +345,6 @@ export default class ObjectEntity extends IEntity {
|
||||
/** @type {ObjectReferenceEntity} */ this.MaterialFunction
|
||||
/** @type {ObjectReferenceEntity} */ this.ObjectRef
|
||||
/** @type {ObjectReferenceEntity} */ this.PCGNode
|
||||
/** @type {ObjectReferenceEntity} */ this.ProxyClass
|
||||
/** @type {ObjectReferenceEntity} */ this.ProxyFactoryClass
|
||||
/** @type {ObjectReferenceEntity} */ this.SettingsInterface
|
||||
/** @type {ObjectReferenceEntity} */ this.StructType
|
||||
/** @type {ObjectReferenceEntity} */ this.TargetType
|
||||
@@ -357,7 +352,6 @@ export default class ObjectEntity extends IEntity {
|
||||
/** @type {String[]} */ this.PinNames
|
||||
/** @type {String} */ this.CustomFunctionName
|
||||
/** @type {String} */ this.DelegatePropertyName
|
||||
/** @type {String} */ this.ErrorMsg
|
||||
/** @type {String} */ this.InputName
|
||||
/** @type {String} */ this.Name
|
||||
/** @type {String} */ this.NodeComment
|
||||
@@ -366,14 +360,11 @@ export default class ObjectEntity extends IEntity {
|
||||
/** @type {String} */ this.ProxyFactoryFunctionName
|
||||
/** @type {String} */ this.SubgraphInstance
|
||||
/** @type {String} */ this.Text
|
||||
/** @type {String} */ this.TimelineName
|
||||
/** @type {SymbolEntity} */ this.AxisKey
|
||||
/** @type {SymbolEntity} */ this.HiGenGridSize
|
||||
/** @type {SymbolEntity} */ this.InputAxisKey
|
||||
/** @type {SymbolEntity} */ this.InputKey
|
||||
/** @type {SymbolEntity} */ this.InputType
|
||||
/** @type {SymbolEntity} */ this.MoveMode
|
||||
/** @type {SymbolEntity} */ this.SelfContextInfo
|
||||
/** @type {VariableReferenceEntity} */ this.DelegateReference
|
||||
/** @type {VariableReferenceEntity} */ this.VariableReference
|
||||
|
||||
@@ -401,11 +392,22 @@ export default class ObjectEntity extends IEntity {
|
||||
const materialSubobject = this.getMaterialSubobject()
|
||||
if (materialSubobject) {
|
||||
const obj = materialSubobject
|
||||
obj.SizeX && (obj.SizeX.getter = () => this.NodeWidth)
|
||||
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)
|
||||
}
|
||||
}
|
||||
/** @type {ObjectEntity} */
|
||||
const pcgObject = this.getPcgSubobject()
|
||||
@@ -705,6 +707,13 @@ export default class ObjectEntity extends IEntity {
|
||||
if (this.StructType) {
|
||||
return `Make ${this.StructType.getName()}`
|
||||
}
|
||||
case Configuration.paths.materialExpressionComponentMask: {
|
||||
const materialObject = this.getMaterialSubobject()
|
||||
return `Mask ( ${Configuration.rgba
|
||||
.filter(k => /** @type {MirroredEntity} */(materialObject[k]).get() === true)
|
||||
.map(v => v + " ")
|
||||
.join("")})`
|
||||
}
|
||||
case Configuration.paths.materialExpressionConstant:
|
||||
input ??= [this.getCustomproperties().find(pinEntity => pinEntity.PinName == "Value")?.DefaultValue]
|
||||
case Configuration.paths.materialExpressionConstant2Vector:
|
||||
@@ -732,11 +741,12 @@ export default class ObjectEntity extends IEntity {
|
||||
return input.map(v => Utility.printExponential(v)).reduce((acc, cur) => acc + "," + cur)
|
||||
}
|
||||
break
|
||||
case Configuration.paths.materialExpressionFunctionInput:
|
||||
case Configuration.paths.materialExpressionFunctionInput: {
|
||||
const materialObject = this.getMaterialSubobject()
|
||||
const inputName = materialObject?.InputName ?? "In"
|
||||
const inputType = materialObject?.InputType?.value.match(/^.+?_(\w+)$/)?.[1] ?? "Vector3"
|
||||
return `Input ${inputName} (${inputType})`
|
||||
}
|
||||
case Configuration.paths.materialExpressionLogarithm:
|
||||
return "Ln"
|
||||
case Configuration.paths.materialExpressionLogarithm10:
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
import Configuration from "../Configuration.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Configuration from "../Configuration.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class ObjectReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
type: {
|
||||
type: new AttributeInfo({
|
||||
default: "",
|
||||
serialized: true,
|
||||
},
|
||||
path: {
|
||||
}),
|
||||
path: new AttributeInfo({
|
||||
default: "",
|
||||
serialized: true,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static quoted = Parsernostrum.regArray(new RegExp(
|
||||
`'"(` + Grammar.Regex.InsideString.source + `)"'`
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class PathSymbolEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
value: new AttributeInfo({
|
||||
default: "",
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import Configuration from "../Configuration.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import ByteEntity from "./ByteEntity.js"
|
||||
import ComputedType from "./ComputedType.js"
|
||||
import Configuration from "../Configuration.js"
|
||||
import EnumDisplayValueEntity from "./EnumDisplayValueEntity.js"
|
||||
import EnumEntity from "./EnumEntity.js"
|
||||
import FormatTextEntity from "./FormatTextEntity.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Integer64Entity from "./Integer64Entity.js"
|
||||
@@ -20,7 +22,6 @@ import SimpleSerializationRotatorEntity from "./SimpleSerializationRotatorEntity
|
||||
import SimpleSerializationVector2DEntity from "./SimpleSerializationVector2DEntity.js"
|
||||
import SimpleSerializationVectorEntity from "./SimpleSerializationVectorEntity.js"
|
||||
import Union from "./Union.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Vector2DEntity from "./Vector2DEntity.js"
|
||||
import VectorEntity from "./VectorEntity.js"
|
||||
|
||||
@@ -49,86 +50,62 @@ export default class PinEntity extends IEntity {
|
||||
[Configuration.paths.vector]: SimpleSerializationVectorEntity,
|
||||
[Configuration.paths.vector2D]: SimpleSerializationVector2DEntity,
|
||||
}
|
||||
static lookbehind = "Pin"
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
objectEntity: {
|
||||
lookbehind: new AttributeInfo({
|
||||
default: "Pin",
|
||||
ignored: true,
|
||||
},
|
||||
pinIndex: {
|
||||
}),
|
||||
objectEntity: new AttributeInfo({
|
||||
ignored: true,
|
||||
}),
|
||||
pinIndex: new AttributeInfo({
|
||||
type: Number,
|
||||
ignored: true,
|
||||
},
|
||||
PinId: {
|
||||
}),
|
||||
PinId: new AttributeInfo({
|
||||
type: GuidEntity,
|
||||
default: () => new GuidEntity()
|
||||
},
|
||||
PinName: {
|
||||
default: "",
|
||||
},
|
||||
PinFriendlyName: {
|
||||
type: new Union(LocalizedTextEntity, FormatTextEntity, String),
|
||||
},
|
||||
PinToolTip: {
|
||||
type: String,
|
||||
},
|
||||
Direction: {
|
||||
type: String,
|
||||
},
|
||||
PinType: {
|
||||
}),
|
||||
PinName: AttributeInfo.createValue(""),
|
||||
PinFriendlyName: AttributeInfo.createType(new Union(LocalizedTextEntity, FormatTextEntity, String)),
|
||||
PinToolTip: AttributeInfo.createType(String),
|
||||
Direction: AttributeInfo.createType(String),
|
||||
PinType: new AttributeInfo({
|
||||
type: PinTypeEntity,
|
||||
default: () => new PinTypeEntity(),
|
||||
inlined: true,
|
||||
},
|
||||
LinkedTo: {
|
||||
type: [PinReferenceEntity],
|
||||
},
|
||||
SubPins: {
|
||||
type: [PinReferenceEntity],
|
||||
},
|
||||
ParentPin: {
|
||||
type: PinReferenceEntity,
|
||||
},
|
||||
DefaultValue: {
|
||||
}),
|
||||
LinkedTo: AttributeInfo.createType([PinReferenceEntity]),
|
||||
SubPins: AttributeInfo.createType([PinReferenceEntity]),
|
||||
ParentPin: AttributeInfo.createType(PinReferenceEntity),
|
||||
DefaultValue: new AttributeInfo({
|
||||
type: new ComputedType(
|
||||
/** @param {PinEntity} pinEntity */
|
||||
pinEntity => pinEntity.getEntityType(true) ?? String
|
||||
),
|
||||
serialized: true,
|
||||
},
|
||||
AutogeneratedDefaultValue: {
|
||||
type: String,
|
||||
},
|
||||
DefaultObject: {
|
||||
type: ObjectReferenceEntity,
|
||||
},
|
||||
PersistentGuid: {
|
||||
type: GuidEntity,
|
||||
},
|
||||
bHidden: {
|
||||
default: false,
|
||||
},
|
||||
bNotConnectable: {
|
||||
default: false,
|
||||
},
|
||||
bDefaultValueIsReadOnly: {
|
||||
default: false,
|
||||
},
|
||||
bDefaultValueIsIgnored: {
|
||||
default: false,
|
||||
},
|
||||
bAdvancedView: {
|
||||
default: false,
|
||||
},
|
||||
bOrphanedPin: {
|
||||
default: false,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
AutogeneratedDefaultValue: AttributeInfo.createType(String),
|
||||
DefaultObject: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
PersistentGuid: AttributeInfo.createType(GuidEntity),
|
||||
bHidden: AttributeInfo.createValue(false),
|
||||
bNotConnectable: AttributeInfo.createValue(false),
|
||||
bDefaultValueIsReadOnly: AttributeInfo.createValue(false),
|
||||
bDefaultValueIsIgnored: AttributeInfo.createValue(false),
|
||||
bAdvancedView: AttributeInfo.createValue(false),
|
||||
bOrphanedPin: AttributeInfo.createValue(false),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
#recomputesNodeTitleOnChange = false
|
||||
set recomputesNodeTitleOnChange(value) {
|
||||
this.#recomputesNodeTitleOnChange = value
|
||||
}
|
||||
get recomputesNodeTitleOnChange() {
|
||||
return this.#recomputesNodeTitleOnChange
|
||||
}
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this)
|
||||
}
|
||||
@@ -166,20 +143,6 @@ export default class PinEntity extends IEntity {
|
||||
if (category === "struct" || category === "object") {
|
||||
return this.PinType.PinSubCategoryObject.path
|
||||
}
|
||||
if (category === "optional") {
|
||||
switch (this.PinType.PinSubCategory) {
|
||||
case "int":
|
||||
return "int"
|
||||
case "red":
|
||||
return "real"
|
||||
case "rg":
|
||||
return "rg"
|
||||
case "rgb":
|
||||
return Configuration.paths.vector
|
||||
case "rgba":
|
||||
return Configuration.paths.linearColor
|
||||
}
|
||||
}
|
||||
if (this.isEnum()) {
|
||||
return "enum"
|
||||
}
|
||||
@@ -209,6 +172,20 @@ export default class PinEntity extends IEntity {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (category === "optional") {
|
||||
switch (this.PinType.PinSubCategory) {
|
||||
case "red":
|
||||
return "real"
|
||||
case "rg":
|
||||
return "rg"
|
||||
case "rgb":
|
||||
return Configuration.paths.vector
|
||||
case "rgba":
|
||||
return Configuration.paths.linearColor
|
||||
default:
|
||||
return this.PinType.PinSubCategory
|
||||
}
|
||||
}
|
||||
return category
|
||||
}
|
||||
|
||||
@@ -291,6 +268,7 @@ export default class PinEntity extends IEntity {
|
||||
/**
|
||||
* @param {String} targetObjectName
|
||||
* @param {PinEntity} targetPinEntity
|
||||
* @returns true if it was not already linked to the tarket
|
||||
*/
|
||||
linkTo(targetObjectName, targetPinEntity) {
|
||||
const linkFound = this.LinkedTo?.some(pinReferenceEntity =>
|
||||
@@ -310,6 +288,7 @@ export default class PinEntity extends IEntity {
|
||||
/**
|
||||
* @param {String} targetObjectName
|
||||
* @param {PinEntity} targetPinEntity
|
||||
* @returns true if it was linked to the target
|
||||
*/
|
||||
unlinkFrom(targetObjectName, targetPinEntity) {
|
||||
const indexElement = this.LinkedTo?.findIndex(pinReferenceEntity => {
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import PathSymbolEntity from "./PathSymbolEntity.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
|
||||
export default class PinReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
objectName: {
|
||||
type: PathSymbolEntity,
|
||||
},
|
||||
pinGuid: {
|
||||
type: GuidEntity,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
objectName: AttributeInfo.createType(PathSymbolEntity),
|
||||
pinGuid: AttributeInfo.createType(GuidEntity),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import FunctionReferenceEntity from "./FunctionReferenceEntity.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import FunctionReferenceEntity from "./FunctionReferenceEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
|
||||
import PathSymbolEntity from "./PathSymbolEntity.js"
|
||||
@@ -8,45 +9,26 @@ export default class PinTypeEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
PinCategory: {
|
||||
default: "",
|
||||
},
|
||||
PinSubCategory: {
|
||||
default: "",
|
||||
},
|
||||
PinSubCategoryObject: {
|
||||
PinCategory: AttributeInfo.createValue(""),
|
||||
PinSubCategory: AttributeInfo.createValue(""),
|
||||
PinSubCategoryObject: new AttributeInfo({
|
||||
type: ObjectReferenceEntity,
|
||||
default: () => ObjectReferenceEntity.createNoneInstance(),
|
||||
},
|
||||
PinSubCategoryMemberReference: {
|
||||
}),
|
||||
PinSubCategoryMemberReference: new AttributeInfo({
|
||||
type: FunctionReferenceEntity,
|
||||
default: null,
|
||||
},
|
||||
PinValueType: {
|
||||
}),
|
||||
PinValueType: new AttributeInfo({
|
||||
type: PinTypeEntity,
|
||||
default: null,
|
||||
},
|
||||
ContainerType: {
|
||||
type: PathSymbolEntity,
|
||||
},
|
||||
bIsReference: {
|
||||
default: false,
|
||||
},
|
||||
bIsConst: {
|
||||
default: false,
|
||||
},
|
||||
bIsWeakPointer: {
|
||||
default: false,
|
||||
},
|
||||
bIsUObjectWrapper: {
|
||||
default: false,
|
||||
},
|
||||
bSerializeAsSinglePrecisionFloat: {
|
||||
default: false,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
ContainerType: AttributeInfo.createType(PathSymbolEntity),
|
||||
bIsReference: AttributeInfo.createValue(false),
|
||||
bIsConst: AttributeInfo.createValue(false),
|
||||
bIsWeakPointer: AttributeInfo.createValue(false),
|
||||
bIsUObjectWrapper: AttributeInfo.createValue(false),
|
||||
bSerializeAsSinglePrecisionFloat: AttributeInfo.createValue(false),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class RotatorEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
R: {
|
||||
R: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
},
|
||||
P: {
|
||||
}),
|
||||
P: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
},
|
||||
Y: {
|
||||
}),
|
||||
Y: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class SymbolEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: {
|
||||
default: "",
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
value: AttributeInfo.createValue(""),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,28 +1,15 @@
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class TerminalTypeEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
TerminalCategory: {
|
||||
type: String,
|
||||
},
|
||||
TerminalSubCategory: {
|
||||
type: String,
|
||||
},
|
||||
bTerminalIsConst: {
|
||||
type: Boolean,
|
||||
},
|
||||
bTerminalIsWeakPointer: {
|
||||
type: Boolean,
|
||||
},
|
||||
bTerminalIsUObjectWrapper: {
|
||||
type: Boolean,
|
||||
},
|
||||
}
|
||||
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
TerminalCategory: AttributeInfo.createType(String),
|
||||
TerminalSubCategory: AttributeInfo.createType(String),
|
||||
bTerminalIsConst: AttributeInfo.createType(Boolean),
|
||||
bTerminalIsWeakPointer: AttributeInfo.createType(Boolean),
|
||||
bTerminalIsUObjectWrapper: AttributeInfo.createType(Boolean),
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
/**
|
||||
* @template {[...U]} T
|
||||
* @template {any[]} U
|
||||
*/
|
||||
/** @template {any[]} T */
|
||||
export default class Union {
|
||||
|
||||
/** @type {T} */
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class UnknownKeysEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
lookbehind: {
|
||||
default: "",
|
||||
ignored: true,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
@@ -44,6 +36,5 @@ export default class UnknownKeysEntity extends IEntity {
|
||||
|
||||
constructor(values) {
|
||||
super(values, true)
|
||||
/** @type {String} */ this.lookbehind
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@ import PinEntity from "./PinEntity.js"
|
||||
|
||||
export default class UnknownPinEntity extends PinEntity {
|
||||
|
||||
static lookbehind = ""
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(
|
||||
new RegExp(`${Grammar.Regex.Symbol.source}\\s*\\(\\s*`),
|
||||
new RegExp(`(${Grammar.Regex.Symbol.source})\\s*\\(\\s*`),
|
||||
1
|
||||
),
|
||||
Grammar.createAttributeGrammar(this).sepBy(Grammar.commaSeparation),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
@@ -6,21 +7,10 @@ export default class VariableReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
MemberScope: {
|
||||
type: String,
|
||||
},
|
||||
MemberName: {
|
||||
default: "",
|
||||
},
|
||||
MemberGuid: {
|
||||
type: GuidEntity,
|
||||
},
|
||||
bSelfContext: {
|
||||
type: Boolean,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
MemberScope: AttributeInfo.createType(String),
|
||||
MemberName: AttributeInfo.createValue(""),
|
||||
MemberGuid: AttributeInfo.createType(GuidEntity),
|
||||
bSelfContext: AttributeInfo.createType(Boolean),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class Vector2DEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
X: {
|
||||
X: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
},
|
||||
Y: {
|
||||
}),
|
||||
Y: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class VectorEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
X: {
|
||||
X: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
},
|
||||
Y: {
|
||||
}),
|
||||
Y: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
},
|
||||
Z: {
|
||||
}),
|
||||
Z: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Configuration from "../Configuration.js"
|
||||
import Utility from "../Utility.js"
|
||||
import AttributeInfo from "../entity/AttributeInfo.js"
|
||||
import IEntity from "../entity/IEntity.js"
|
||||
import MirroredEntity from "../entity/MirroredEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Serializable from "./Serializable.js"
|
||||
import Union from "../entity/Union.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Serializable from "./Serializable.js"
|
||||
|
||||
export default class Grammar {
|
||||
|
||||
@@ -66,16 +67,10 @@ export default class Grammar {
|
||||
/* --- Factory --- */
|
||||
|
||||
/**
|
||||
* @template {AttributeTypeDescription} T
|
||||
* @param {T} type
|
||||
* @template T
|
||||
* @param {AttributeInfo<T>} attribute
|
||||
*/
|
||||
static grammarFor(
|
||||
attribute,
|
||||
type = attribute?.constructor === Object
|
||||
? attribute.type
|
||||
: attribute?.constructor,
|
||||
defaultGrammar = this.unknownValue
|
||||
) {
|
||||
static grammarFor(attribute, type = attribute?.type, defaultGrammar = this.unknownValue) {
|
||||
let result = defaultGrammar
|
||||
if (type instanceof Array) {
|
||||
if (attribute?.inlined) {
|
||||
@@ -103,6 +98,9 @@ export default class Grammar {
|
||||
case Boolean:
|
||||
result = this.boolean
|
||||
break
|
||||
case null:
|
||||
result = this.null
|
||||
break
|
||||
case Number:
|
||||
result = this.number
|
||||
break
|
||||
@@ -114,11 +112,11 @@ export default class Grammar {
|
||||
break
|
||||
default:
|
||||
if (/** @type {AttributeConstructor<any>} */(type)?.prototype instanceof Serializable) {
|
||||
return /** @type {typeof Serializable} */(type).grammar
|
||||
result = /** @type {typeof Serializable} */(type).grammar
|
||||
}
|
||||
}
|
||||
}
|
||||
if (attribute?.constructor === Object) {
|
||||
if (attribute) {
|
||||
if (attribute.serialized && type.constructor !== String) {
|
||||
if (result == this.unknownValue) {
|
||||
result = this.string
|
||||
@@ -137,7 +135,7 @@ export default class Grammar {
|
||||
* @template {AttributeConstructor<Attribute>} T
|
||||
* @param {T} entityType
|
||||
* @param {String[]} key
|
||||
* @returns {AttributeInformation}
|
||||
* @returns {AttributeInfo}
|
||||
*/
|
||||
static getAttribute(entityType, key) {
|
||||
let result
|
||||
@@ -191,13 +189,14 @@ export default class Grammar {
|
||||
* @param {(new (...args: any) => T) & EntityConstructor} entityType
|
||||
* @param {Boolean | Number} acceptUnknownKeys Number to specify the limit or true, to let it be a reasonable value
|
||||
*/
|
||||
static createEntityGrammar = (entityType, acceptUnknownKeys = true, entriesSeparator = this.commaSeparation) =>
|
||||
Parsernostrum.seq(
|
||||
static createEntityGrammar(entityType, acceptUnknownKeys = true, entriesSeparator = this.commaSeparation) {
|
||||
const lookbehind = entityType.attributes.lookbehind.default
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(
|
||||
entityType.lookbehind instanceof Union
|
||||
? new RegExp(`(${entityType.lookbehind.values.reduce((acc, cur) => acc + "|" + cur)})\\s*\\(\\s*`)
|
||||
: entityType.lookbehind.constructor == String && entityType.lookbehind.length
|
||||
? new RegExp(`(${entityType.lookbehind})\\s*\\(\\s*`)
|
||||
lookbehind instanceof Union
|
||||
? new RegExp(`(${lookbehind.values.reduce((acc, cur) => acc + "|" + cur)})\\s*\\(\\s*`)
|
||||
: lookbehind.constructor == String && lookbehind.length > 0
|
||||
? new RegExp(`(${lookbehind})\\s*\\(\\s*`)
|
||||
: /()\(\s*/,
|
||||
1
|
||||
),
|
||||
@@ -218,7 +217,7 @@ export default class Grammar {
|
||||
let missingKey
|
||||
// Check missing values
|
||||
if (
|
||||
Object.keys(/** @type {AttributeInformation} */(entityType.attributes))
|
||||
Object.keys(/** @type {AttributeDeclarations} */(entityType.attributes))
|
||||
.filter(key => entityType.attributes[key].expected)
|
||||
.find(key => !totalKeys.includes(key) && (missingKey = key))
|
||||
) {
|
||||
@@ -230,6 +229,7 @@ export default class Grammar {
|
||||
}
|
||||
return Parsernostrum.success().map(() => new entityType(values))
|
||||
})
|
||||
}
|
||||
|
||||
/* --- Entity --- */
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Configuration from "../Configuration.js"
|
||||
import Grammar from "./Grammar.js"
|
||||
import ObjectEntity from "../entity/ObjectEntity.js"
|
||||
import PinEntity from "../entity/PinEntity.js"
|
||||
import Grammar from "./Grammar.js"
|
||||
import Serializer from "./Serializer.js"
|
||||
import SerializerFactory from "./SerializerFactory.js"
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import Grammar from "./Grammar.js"
|
||||
import IEntity from "../entity/IEntity.js"
|
||||
import SerializerFactory from "./SerializerFactory.js"
|
||||
import Utility from "../Utility.js"
|
||||
import AttributeInfo from "../entity/AttributeInfo.js"
|
||||
import IEntity from "../entity/IEntity.js"
|
||||
import Grammar from "./Grammar.js"
|
||||
import SerializerFactory from "./SerializerFactory.js"
|
||||
|
||||
/** @template {AttributeConstructor<Attribute>} T */
|
||||
export default class Serializer {
|
||||
@@ -54,7 +55,11 @@ export default class Serializer {
|
||||
let grammar = Grammar.grammarFor(undefined, this.entityType)
|
||||
const parseResult = grammar.run(value)
|
||||
if (!parseResult.status) {
|
||||
throw new Error(`Error when trying to parse the entity ${this.entityType.prototype.constructor.name}.`)
|
||||
throw new Error(
|
||||
this.entityType
|
||||
? `Error when trying to parse the entity ${this.entityType.prototype.constructor.name}`
|
||||
: "Error when trying to parse null"
|
||||
)
|
||||
}
|
||||
return parseResult.value
|
||||
}
|
||||
@@ -85,7 +90,7 @@ export default class Serializer {
|
||||
if (attributes[key]?.quoted) {
|
||||
keyValue = `"${keyValue}"`
|
||||
}
|
||||
const isSerialized = Utility.isSerialized(entity, key)
|
||||
const isSerialized = AttributeInfo.getAttribute(entity, key, "serialized")
|
||||
if (first) {
|
||||
first = false
|
||||
} else {
|
||||
@@ -140,10 +145,21 @@ export default class Serializer {
|
||||
return serializer.doWrite(value, insideString, indentation)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {IEntity} entity
|
||||
* @param {String} key
|
||||
*/
|
||||
showProperty(entity, key) {
|
||||
const attribute = /** @type {EntityConstructor} */(this.entityType).attributes[key]
|
||||
if (attribute?.constructor === Object && attribute.ignored) {
|
||||
return false
|
||||
if (entity instanceof IEntity) {
|
||||
if (
|
||||
AttributeInfo.getAttribute(entity, key, "ignored")
|
||||
|| AttributeInfo.getAttribute(entity, key, "silent") && Utility.equals(
|
||||
AttributeInfo.getAttribute(entity, key, "default"),
|
||||
entity[key]
|
||||
)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Serializer from "./Serializer.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Serializer from "./Serializer.js"
|
||||
|
||||
/**
|
||||
* @template {AttributeConstructor<Attribute>} T
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Utility from "../Utility.js"
|
||||
import ByteEntity from "../entity/ByteEntity.js"
|
||||
import ColorChannelEntity from "../entity/ColorChannelEntity.js"
|
||||
import CustomSerializer from "./CustomSerializer.js"
|
||||
import EnumDisplayValueEntity from "../entity/EnumDisplayValueEntity.js"
|
||||
import EnumEntity from "../entity/EnumEntity.js"
|
||||
import FormatTextEntity from "../entity/FormatTextEntity.js"
|
||||
import FunctionReferenceEntity from "../entity/FunctionReferenceEntity.js"
|
||||
import Grammar from "./Grammar.js"
|
||||
import GuidEntity from "../entity/GuidEntity.js"
|
||||
import IdentifierEntity from "../entity/IdentifierEntity.js"
|
||||
import Integer64Entity from "../entity/Integer64Entity.js"
|
||||
@@ -18,27 +18,28 @@ import MacroGraphReferenceEntity from "../entity/MacroGraphReferenceEntity.js"
|
||||
import MirroredEntity from "../entity/MirroredEntity.js"
|
||||
import ObjectEntity from "../entity/ObjectEntity.js"
|
||||
import ObjectReferenceEntity from "../entity/ObjectReferenceEntity.js"
|
||||
import ObjectSerializer from "./ObjectSerializer.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import PathSymbolEntity from "../entity/PathSymbolEntity.js"
|
||||
import PinEntity from "../entity/PinEntity.js"
|
||||
import PinReferenceEntity from "../entity/PinReferenceEntity.js"
|
||||
import RBSerializationVector2DEntity from "../entity/RBSerializationVector2DEntity.js"
|
||||
import RotatorEntity from "../entity/RotatorEntity.js"
|
||||
import Serializer from "./Serializer.js"
|
||||
import SerializerFactory from "./SerializerFactory.js"
|
||||
import SimpleSerializationRotatorEntity from "../entity/SimpleSerializationRotatorEntity.js"
|
||||
import SimpleSerializationVector2DEntity from "../entity/SimpleSerializationVector2DEntity.js"
|
||||
import SimpleSerializationVectorEntity from "../entity/SimpleSerializationVectorEntity.js"
|
||||
import SymbolEntity from "../entity/SymbolEntity.js"
|
||||
import TerminalTypeEntity from "../entity/TerminalTypeEntity.js"
|
||||
import ToStringSerializer from "./ToStringSerializer.js"
|
||||
import Union from "../entity/Union.js"
|
||||
import UnknownKeysEntity from "../entity/UnknownKeysEntity.js"
|
||||
import Utility from "../Utility.js"
|
||||
import VariableReferenceEntity from "../entity/VariableReferenceEntity.js"
|
||||
import Vector2DEntity from "../entity/Vector2DEntity.js"
|
||||
import VectorEntity from "../entity/VectorEntity.js"
|
||||
import CustomSerializer from "./CustomSerializer.js"
|
||||
import Grammar from "./Grammar.js"
|
||||
import ObjectSerializer from "./ObjectSerializer.js"
|
||||
import Serializer from "./Serializer.js"
|
||||
import SerializerFactory from "./SerializerFactory.js"
|
||||
import ToStringSerializer from "./ToStringSerializer.js"
|
||||
import PinTypeEntity from "../entity/PinTypeEntity.js"
|
||||
|
||||
Grammar.unknownValue =
|
||||
Parsernostrum.alt(
|
||||
@@ -48,8 +49,8 @@ Grammar.unknownValue =
|
||||
Parsernostrum.str("None").map(() => new ObjectReferenceEntity({ type: "None" })),
|
||||
Grammar.null,
|
||||
Grammar.number,
|
||||
Grammar.string,
|
||||
ObjectReferenceEntity.fullReferenceGrammar,
|
||||
Grammar.string,
|
||||
LocalizedTextEntity.createGrammar(),
|
||||
InvariantTextEntity.createGrammar(),
|
||||
FormatTextEntity.createGrammar(),
|
||||
@@ -244,6 +245,11 @@ export default function initializeSerializerFactory() {
|
||||
new Serializer(PinReferenceEntity, undefined, " ", false, "", () => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinTypeEntity,
|
||||
new Serializer(PinTypeEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
TerminalTypeEntity,
|
||||
new Serializer(TerminalTypeEntity, Serializer.bracketsWrapped)
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { html } from "lit"
|
||||
import Configuration from "../Configuration.js"
|
||||
import Shortcuts from "../Shortcuts.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Copy from "../input/common/Copy.js"
|
||||
import Cut from "../input/common/Cut.js"
|
||||
import ITemplate from "./ITemplate.js"
|
||||
import Paste from "../input/common/Paste.js"
|
||||
import KeyboardEnableZoom from "../input/keyboard/KeyboardEnableZoom.js"
|
||||
import KeyboardShortcut from "../input/keyboard/KeyboardShortcut.js"
|
||||
import MouseScrollGraph from "../input/mouse/MouseScrollGraph.js"
|
||||
import MouseTracking from "../input/mouse/MouseTracking.js"
|
||||
import Paste from "../input/common/Paste.js"
|
||||
import Select from "../input/mouse/Select.js"
|
||||
import Shortcuts from "../Shortcuts.js"
|
||||
import Unfocus from "../input/mouse/Unfocus.js"
|
||||
import Utility from "../Utility.js"
|
||||
import Zoom from "../input/mouse/Zoom.js"
|
||||
import ITemplate from "./ITemplate.js"
|
||||
|
||||
/** @extends ITemplate<Blueprint> */
|
||||
export default class BlueprintTemplate extends ITemplate {
|
||||
@@ -37,10 +37,13 @@ export default class BlueprintTemplate extends ITemplate {
|
||||
this.viewportSize[1] = size.blockSize
|
||||
}
|
||||
})
|
||||
|
||||
/** @type {Copy} */
|
||||
#copyInputObject
|
||||
|
||||
/** @type {Paste} */
|
||||
#pasteInputObject
|
||||
|
||||
/** @type {Zoom} */
|
||||
#zoomInputObject
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import IDraggableControlTemplate from "./IDraggableControlTemplate.js"
|
||||
import Utility from "../Utility.js"
|
||||
import IDraggableControlTemplate from "./IDraggableControlTemplate.js"
|
||||
|
||||
/** @extends {IDraggableControlTemplate<ColorHandlerElement>} */
|
||||
export default class ColorHandlerTemplate extends IDraggableControlTemplate {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import IDraggableControlTemplate from "./IDraggableControlTemplate.js"
|
||||
import Utility from "../Utility.js"
|
||||
import IDraggableControlTemplate from "./IDraggableControlTemplate.js"
|
||||
|
||||
/** @extends {IDraggableControlTemplate<ColorHandlerElement>} */
|
||||
export default class ColorSliderTemplate extends IDraggableControlTemplate {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import IDraggableTemplate from "./IDraggableTemplate.js"
|
||||
import MouseMoveDraggable from "../input/mouse/MouseMoveDraggable.js"
|
||||
import IDraggableTemplate from "./IDraggableTemplate.js"
|
||||
|
||||
/**
|
||||
* @template {IDraggableElement} T
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Configuration from "../Configuration.js"
|
||||
import ITemplate from "./ITemplate.js"
|
||||
import KeyboardShortcut from "../input/keyboard/KeyboardShortcut.js"
|
||||
import MouseMoveDraggable from "../input/mouse/MouseMoveDraggable.js"
|
||||
import ITemplate from "./ITemplate.js"
|
||||
|
||||
/**
|
||||
* @template {IDraggableElement} T
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import IDraggablePositionedTemplate from "./IDraggablePositionedTemplate.js"
|
||||
import MouseMoveNodes from "../input/mouse/MouseMoveNodes.js"
|
||||
import IDraggablePositionedTemplate from "./IDraggablePositionedTemplate.js"
|
||||
|
||||
/**
|
||||
* @template {NodeElement} T
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { html, nothing } from "lit"
|
||||
import Configuration from "../Configuration.js"
|
||||
import ElementFactory from "../element/ElementFactory.js"
|
||||
import IFromToPositionedTemplate from "./IFromToPositionedTemplate.js"
|
||||
import KeyboardShortcut from "../input/keyboard/KeyboardShortcut.js"
|
||||
import KnotEntity from "../entity/objects/KnotEntity.js"
|
||||
import MouseClick from "../input/mouse/MouseClick.js"
|
||||
import MouseDbClick from "../input/mouse/MouseDbClick.js"
|
||||
import Shortcuts from "../Shortcuts.js"
|
||||
import Utility from "../Utility.js"
|
||||
import ElementFactory from "../element/ElementFactory.js"
|
||||
import KnotEntity from "../entity/objects/KnotEntity.js"
|
||||
import KeyboardShortcut from "../input/keyboard/KeyboardShortcut.js"
|
||||
import MouseClick from "../input/mouse/MouseClick.js"
|
||||
import MouseDbClick from "../input/mouse/MouseDbClick.js"
|
||||
import IFromToPositionedTemplate from "./IFromToPositionedTemplate.js"
|
||||
|
||||
/** @extends {IFromToPositionedTemplate<LinkElement>} */
|
||||
export default class LinkTemplate extends IFromToPositionedTemplate {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { html, nothing } from "lit"
|
||||
import ElementFactory from "../../element/ElementFactory.js"
|
||||
import ISelectableDraggableTemplate from "../ISelectableDraggableTemplate.js"
|
||||
import SVGIcon from "../../SVGIcon.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import ElementFactory from "../../element/ElementFactory.js"
|
||||
import ISelectableDraggableTemplate from "../ISelectableDraggableTemplate.js"
|
||||
|
||||
/** @extends {ISelectableDraggableTemplate<NodeElement>} */
|
||||
export default class NodeTemplate extends ISelectableDraggableTemplate {
|
||||
@@ -99,7 +99,7 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
|
||||
}
|
||||
|
||||
renderNodeName() {
|
||||
return this.element.getNodeDisplayName()
|
||||
return this.element.nodeDisplayName
|
||||
}
|
||||
|
||||
renderTop() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { html, nothing } from "lit"
|
||||
import SVGIcon from "../../SVGIcon.js"
|
||||
import ElementFactory from "../../element/ElementFactory.js"
|
||||
import NodeTemplate from "./NodeTemplate.js"
|
||||
import SVGIcon from "../../SVGIcon.js"
|
||||
|
||||
export default class VariableManagementNodeTemplate extends NodeTemplate {
|
||||
|
||||
@@ -14,7 +14,7 @@ export default class VariableManagementNodeTemplate extends NodeTemplate {
|
||||
/** @param {NodeElement} element */
|
||||
initialize(element) {
|
||||
super.initialize(element)
|
||||
this.#displayName = this.element.getNodeDisplayName()
|
||||
this.#displayName = this.element.nodeDisplayName
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -35,7 +35,7 @@ export default class BoolPinTemplate extends PinTemplate {
|
||||
|
||||
renderInput() {
|
||||
return html`
|
||||
<input type="checkbox" class="ueb-pin-input-wrapper ueb-pin-input" ?checked="${this.element.defaultValue}" />
|
||||
<input type="checkbox" class="ueb-pin-input-wrapper ueb-pin-input" ?checked="${this.element.defaultValue === true}" />
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { html } from "lit"
|
||||
import ITemplate from "../ITemplate.js"
|
||||
import MouseIgnore from "../../input/mouse/MouseIgnore.js"
|
||||
import ITemplate from "../ITemplate.js"
|
||||
|
||||
/** @extends {ITemplate<DropdownElement>} */
|
||||
export default class DropdownTemplate extends ITemplate {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { html } from "lit"
|
||||
import Configuration from "../../Configuration.js"
|
||||
import IInputPinTemplate from "./IInputPinTemplate.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import IInputPinTemplate from "./IInputPinTemplate.js"
|
||||
|
||||
/** @extends IInputPinTemplate<EnumEntity> */
|
||||
export default class EnumPinTemplate extends IInputPinTemplate {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { html } from "lit"
|
||||
import PinTemplate from "./PinTemplate.js"
|
||||
import SVGIcon from "../../SVGIcon.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import PinTemplate from "./PinTemplate.js"
|
||||
|
||||
export default class ExecPinTemplate extends PinTemplate {
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { html } from "lit"
|
||||
import Configuration from "../../Configuration.js"
|
||||
import PinTemplate from "./PinTemplate.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import PinTemplate from "./PinTemplate.js"
|
||||
|
||||
/**
|
||||
* @template {TerminalAttribute} T
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import ITemplate from "../ITemplate.js"
|
||||
import MouseIgnore from "../../input/mouse/MouseIgnore.js"
|
||||
import ITemplate from "../ITemplate.js"
|
||||
|
||||
/** @extends {ITemplate<InputElement>} */
|
||||
export default class InputTemplate extends ITemplate {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { html } from "lit"
|
||||
import MinimalPinTemplate from "./MinimalPinTemplate.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import MinimalPinTemplate from "./MinimalPinTemplate.js"
|
||||
|
||||
/** @extends MinimalPinTemplate<KnotEntity> */
|
||||
export default class KnotPinTemplate extends MinimalPinTemplate {
|
||||
@@ -21,6 +21,7 @@ export default class KnotPinTemplate extends MinimalPinTemplate {
|
||||
: this
|
||||
)
|
||||
.iconElement.getBoundingClientRect()
|
||||
/** @type {Coordinates} */
|
||||
const boundingLocation = [this.element.isInput() ? rect.left : rect.right + 1, (rect.top + rect.bottom) / 2]
|
||||
const location = Utility.convertLocation(boundingLocation, this.blueprint.template.gridElement)
|
||||
return this.blueprint.compensateTranslation(location[0], location[1])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { html, nothing } from "lit"
|
||||
import ColorPickerWindowTemplate from "../window/ColorPickerWindowTemplate.js"
|
||||
import Configuration from "../../Configuration.js"
|
||||
import ElementFactory from "../../element/ElementFactory.js"
|
||||
import ColorPickerWindowTemplate from "../window/ColorPickerWindowTemplate.js"
|
||||
import PinTemplate from "./PinTemplate.js"
|
||||
|
||||
/** @extends PinTemplate<LinearColorEntity> */
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { html, nothing } from "lit"
|
||||
import Configuration from "../../Configuration.js"
|
||||
import ITemplate from "../ITemplate.js"
|
||||
import MouseCreateLink from "../../input/mouse/MouseCreateLink.js"
|
||||
import SVGIcon from "../../SVGIcon.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import MouseCreateLink from "../../input/mouse/MouseCreateLink.js"
|
||||
import ITemplate from "../ITemplate.js"
|
||||
import VariableConversionNodeTemplate from "../node/VariableConversionNodeTemplate.js"
|
||||
import VariableOperationNodeTemplate from "../node/VariableOperationNodeTemplate.js"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { html } from "lit"
|
||||
import INumericPinTemplate from "./INumericPinTemplate.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import INumericPinTemplate from "./INumericPinTemplate.js"
|
||||
|
||||
/**
|
||||
* @template {Number} T
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import PinTemplate from "./PinTemplate.js"
|
||||
import SVGIcon from "../../SVGIcon.js"
|
||||
import PinTemplate from "./PinTemplate.js"
|
||||
|
||||
export default class ReferencePinTemplate extends PinTemplate {
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { html } from "lit"
|
||||
import INumericPinTemplate from "./INumericPinTemplate.js"
|
||||
import RotatorEntity from "../../entity/RotatorEntity.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import RotatorEntity from "../../entity/RotatorEntity.js"
|
||||
import INumericPinTemplate from "./INumericPinTemplate.js"
|
||||
|
||||
/** @extends INumericPinTemplate<RotatorEntity> */
|
||||
export default class RotatorPinTemplate extends INumericPinTemplate {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { html } from "lit"
|
||||
import INumericPinTemplate from "./INumericPinTemplate.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import Vector2DEntity from "../../entity/Vector2DEntity.js"
|
||||
import INumericPinTemplate from "./INumericPinTemplate.js"
|
||||
|
||||
/**
|
||||
* @extends INumericPinTemplate<Vector2DEntity>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { html } from "lit"
|
||||
import INumericPinTemplate from "./INumericPinTemplate.js"
|
||||
import Utility from "../../Utility.js"
|
||||
import VectorEntity from "../../entity/VectorEntity.js"
|
||||
import INumericPinTemplate from "./INumericPinTemplate.js"
|
||||
|
||||
/** @extends INumericPinTemplate<VectorEntity> */
|
||||
export default class VectorPinTemplate extends INumericPinTemplate {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "ueblueprint",
|
||||
"version": "1.0.0",
|
||||
"description": "UE's Blueprint visualisation library",
|
||||
"type": "module",
|
||||
"description": "UE's Blueprint visualisation library",
|
||||
"main": "dist/ueblueprint.js",
|
||||
"types": "types.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, expect } from "./fixtures/test.js"
|
||||
import BlueprintFixture from "./fixtures/BlueprintFixture.js"
|
||||
import Configuration from "../js/Configuration.js"
|
||||
import BlueprintFixture from "./fixtures/BlueprintFixture.js"
|
||||
import { expect, test } from "./fixtures/test.js"
|
||||
|
||||
test.describe("Color picker", () => {
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { test, expect } from "./fixtures/test.js"
|
||||
import Entity1 from "./resources/Entity1.js"
|
||||
import Entity2 from "./resources/Entity2.js"
|
||||
import entity2Value from "./resources/serializedEntity2.js"
|
||||
import Entity3 from "./resources/Entity3.js"
|
||||
import entity3Value from "./resources/serializedEntity3.js"
|
||||
import Entity4 from "./resources/Entity4.js"
|
||||
import entity4Value from "./resources/serializedEntity4.js"
|
||||
import Entity5 from "./resources/Entity5.js"
|
||||
import entity5Value1 from "./resources/serializedEntity5-1.js"
|
||||
import EntityF from "./resources/EntityF.js"
|
||||
import UnknownKeysEntity from "../js/entity/UnknownKeysEntity.js"
|
||||
import Grammar from "../js/serialization/Grammar.js"
|
||||
import initializeSerializerFactory from "../js/serialization/initializeSerializerFactory.js"
|
||||
import ObjectSerializer from "../js/serialization/ObjectSerializer.js"
|
||||
import Serializer from "../js/serialization/Serializer.js"
|
||||
import SerializerFactory from "../js/serialization/SerializerFactory.js"
|
||||
import UnknownKeysEntity from "../js/entity/UnknownKeysEntity.js"
|
||||
import initializeSerializerFactory from "../js/serialization/initializeSerializerFactory.js"
|
||||
import { expect, test } from "./fixtures/test.js"
|
||||
import Entity1 from "./resources/Entity1.js"
|
||||
import Entity2 from "./resources/Entity2.js"
|
||||
import Entity3 from "./resources/Entity3.js"
|
||||
import Entity4 from "./resources/Entity4.js"
|
||||
import Entity5 from "./resources/Entity5.js"
|
||||
import EntityF from "./resources/EntityF.js"
|
||||
import entity2Value from "./resources/serializedEntity2.js"
|
||||
import entity3Value from "./resources/serializedEntity3.js"
|
||||
import entity4Value from "./resources/serializedEntity4.js"
|
||||
import entity5Value1 from "./resources/serializedEntity5-1.js"
|
||||
|
||||
test.describe.configure({ mode: "parallel" })
|
||||
|
||||
@@ -31,7 +31,7 @@ test("Entity2", () => {
|
||||
Entity1,
|
||||
new Serializer(Entity1, (entity, v) => `Entity1(${v})`, ", ", false, "=",)
|
||||
)
|
||||
expect(Object.keys(entity)).toHaveLength(8)
|
||||
expect(Object.keys(entity)).toHaveLength(9)
|
||||
expect(entity.someNumber).toBe(567)
|
||||
expect(entity.someString).toBe("alpha")
|
||||
expect(entity.someString2).toBe("beta")
|
||||
@@ -39,6 +39,7 @@ test("Entity2", () => {
|
||||
expect(entity.someBoolean2).toBe(false)
|
||||
expect(entity.someObjectString).toBe("gamma")
|
||||
expect(entity.someArray).toStrictEqual([400, 500, 600, 700, 800])
|
||||
expect(entity.someArray2).toStrictEqual([400, 500, 600, 700, 800])
|
||||
|
||||
expect(entity.equals(new Entity2())).toBeTruthy()
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { test, expect } from "./fixtures/test.js"
|
||||
import Utility from "../js/Utility.js"
|
||||
import Configuration from "./../js/Configuration.js"
|
||||
import { expect, test } from "./fixtures/test.js"
|
||||
import EventNodes from "./resources/EventNodes.js"
|
||||
import FlowControlNodes from "./resources/FlowControlNodes.js"
|
||||
import InputNodes from "./resources/InputNodes.js"
|
||||
import IssuesNodes1 from "./resources/IssuesNodes1.js"
|
||||
import LegacyNodes from "./resources/LegacyNodes.js"
|
||||
import MaterialNodes from "./resources/MaterialNodes.js"
|
||||
import OperationsNodes from "./resources/OperationsNodes.js"
|
||||
@@ -17,15 +19,10 @@ const nodeTests = [
|
||||
...MaterialNodes.get(),
|
||||
...OperationsNodes.get(),
|
||||
...OtherNodes.get(),
|
||||
...PCGNodes.get()
|
||||
...PCGNodes.get(),
|
||||
...IssuesNodes1.get(),
|
||||
]
|
||||
|
||||
/** @param {String[]} words */
|
||||
function getFirstWordOrder(words) {
|
||||
return new RegExp(/\s*/.source + words.join(/[^\n]+\n\s*/.source) + /\s*/.source)
|
||||
}
|
||||
|
||||
|
||||
test.describe.configure({ mode: "parallel" })
|
||||
|
||||
for (const nodeTest of nodeTests) {
|
||||
@@ -63,7 +60,7 @@ for (const nodeTest of nodeTests) {
|
||||
test(
|
||||
`${nodeTest.name}: Has title ${nodeTest.title}`,
|
||||
async ({ blueprintPage }) => expect(
|
||||
await blueprintPage.node.evaluate(node => node.getNodeDisplayName())
|
||||
await blueprintPage.node.evaluate(node => node.nodeDisplayName)
|
||||
).toBe(nodeTest.title)
|
||||
)
|
||||
}
|
||||
@@ -136,15 +133,15 @@ for (const nodeTest of nodeTests) {
|
||||
test(
|
||||
`${nodeTest.name}: Maintains the order of attributes`,
|
||||
async ({ blueprintPage }) => {
|
||||
const value = await blueprintPage.blueprintLocator.evaluate(blueprint => {
|
||||
const serialized = await blueprintPage.blueprintLocator.evaluate(blueprint => {
|
||||
blueprint.selectAll()
|
||||
return blueprint.template.getCopyInputObject().getSerializedText()
|
||||
})
|
||||
const words = value
|
||||
const words = nodeTest.value
|
||||
.split("\n")
|
||||
.map(row => row.match(/\s*("?\w+(\s+\w+)*).+/)?.[1])
|
||||
.filter(v => v?.length > 0)
|
||||
expect(value).toMatch(getFirstWordOrder(words))
|
||||
expect(serialized).toMatch(Utility.getFirstWordOrder(words))
|
||||
}
|
||||
)
|
||||
if (nodeTest.variadic) {
|
||||
@@ -162,7 +159,11 @@ for (const nodeTest of nodeTests) {
|
||||
test(
|
||||
`${nodeTest.name}: Additional tests`,
|
||||
async ({ blueprintPage }) =>
|
||||
nodeTest.additionalTest(blueprintPage.node, await blueprintPage.node.locator("ueb-pin").all())
|
||||
nodeTest.additionalTest(
|
||||
blueprintPage.node,
|
||||
await blueprintPage.node.locator("ueb-pin").all(),
|
||||
blueprintPage,
|
||||
)
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
import { test, expect } from "@playwright/test"
|
||||
import { expect, test } from "@playwright/test"
|
||||
import Utility from "../js/Utility.js"
|
||||
import FormatTextEntity from "../js/entity/FormatTextEntity.js"
|
||||
import Grammar from "../js/serialization/Grammar.js"
|
||||
import GuidEntity from "../js/entity/GuidEntity.js"
|
||||
import initializeSerializerFactory from "../js/serialization/initializeSerializerFactory.js"
|
||||
import IntegerEntity from "../js/entity/IntegerEntity.js"
|
||||
import KeyBindingEntity from "../js/entity/KeyBindingEntity.js"
|
||||
import LinearColorEntity from "../js/entity/LinearColorEntity.js"
|
||||
import ObjectReferenceEntity from "../js/entity/ObjectReferenceEntity.js"
|
||||
import PinTypeEntity from "../js/entity/PinTypeEntity.js"
|
||||
import RotatorEntity from "../js/entity/RotatorEntity.js"
|
||||
import SerializerFactory from "../js/serialization/SerializerFactory.js"
|
||||
import SymbolEntity from "../js/entity/SymbolEntity.js"
|
||||
import UnknownKeysEntity from "../js/entity/UnknownKeysEntity.js"
|
||||
import Utility from "../js/Utility.js"
|
||||
import Vector2DEntity from "../js/entity/Vector2DEntity.js"
|
||||
import VectorEntity from "../js/entity/VectorEntity.js"
|
||||
import Grammar from "../js/serialization/Grammar.js"
|
||||
import SerializerFactory from "../js/serialization/SerializerFactory.js"
|
||||
import initializeSerializerFactory from "../js/serialization/initializeSerializerFactory.js"
|
||||
import PinEntity from "../js/entity/PinEntity.js"
|
||||
|
||||
initializeSerializerFactory()
|
||||
test.beforeAll(() => initializeSerializerFactory())
|
||||
|
||||
test.describe.configure({ mode: "parallel" })
|
||||
|
||||
@@ -168,6 +170,15 @@ test("LinearColorEntity", () => {
|
||||
expect(() => serializer.read("(R=0.000000,G=\"hello\",A=1.000000)")).toThrow()
|
||||
})
|
||||
|
||||
test("Null", () => {
|
||||
const serializer = SerializerFactory.getSerializer(null)
|
||||
|
||||
expect(serializer.read("()")).toBeNull()
|
||||
expect(() => serializer.read("123")).toThrow()
|
||||
expect(() => serializer.read("(a)")).toThrow()
|
||||
expect(() => serializer.read("(")).toThrow()
|
||||
})
|
||||
|
||||
test("Number", () => {
|
||||
const serializer = SerializerFactory.getSerializer(Number)
|
||||
|
||||
@@ -280,6 +291,14 @@ test("ObjectReferenceEntity", () => {
|
||||
})
|
||||
})
|
||||
|
||||
test("PinEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(PinEntity)
|
||||
|
||||
expect(serializer.read("Pin (PinType.PinSubCategoryMemberReference=())")).toMatchObject({
|
||||
"PinType": { "PinSubCategoryMemberReference": null }
|
||||
})
|
||||
})
|
||||
|
||||
test("String", () => {
|
||||
const serializer = SerializerFactory.getSerializer(String)
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
|
||||
export default class Entity1 extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
a: {
|
||||
a: new AttributeInfo({
|
||||
type: Number,
|
||||
default: 8,
|
||||
},
|
||||
b: {
|
||||
}),
|
||||
b: new AttributeInfo({
|
||||
type: Number,
|
||||
default: 9,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
constructor(values = {}) {
|
||||
|
||||
@@ -1,37 +1,21 @@
|
||||
import Entity1 from "./Entity1.js"
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import Entity1 from "./Entity1.js"
|
||||
|
||||
export default class Entity2 extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
someNumber: {
|
||||
default: 567,
|
||||
},
|
||||
someString: {
|
||||
default: "alpha",
|
||||
},
|
||||
someString2: {
|
||||
default: "beta",
|
||||
},
|
||||
someBoolean: {
|
||||
default: true,
|
||||
},
|
||||
someBoolean2: {
|
||||
default: false,
|
||||
},
|
||||
someObjectString: {
|
||||
default: "gamma",
|
||||
},
|
||||
someArray: {
|
||||
default: [400, 500, 600, 700, 800],
|
||||
},
|
||||
someEntity: {
|
||||
someNumber: AttributeInfo.createValue(567),
|
||||
someString: AttributeInfo.createValue("alpha"),
|
||||
someString2: AttributeInfo.createValue("beta"),
|
||||
someBoolean: AttributeInfo.createValue(true),
|
||||
someBoolean2: AttributeInfo.createValue(false),
|
||||
someObjectString: AttributeInfo.createValue("gamma"),
|
||||
someArray: AttributeInfo.createValue([400, 500, 600, 700, 800]),
|
||||
someArray2: AttributeInfo.createValue(() => [400, 500, 600, 700, 800]),
|
||||
someEntity: new AttributeInfo({
|
||||
type: Entity1,
|
||||
default: new Entity1()
|
||||
},
|
||||
}
|
||||
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,87 +1,74 @@
|
||||
import Entity1 from "./Entity1.js"
|
||||
import Entity2 from "./Entity2.js"
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import Union from "../../js/entity/Union.js"
|
||||
import Entity1 from "./Entity1.js"
|
||||
import Entity2 from "./Entity2.js"
|
||||
|
||||
export default class Entity3 extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
alpha: {
|
||||
default: 32,
|
||||
},
|
||||
bravo: {
|
||||
alpha: AttributeInfo.createValue(32),
|
||||
bravo: new AttributeInfo({
|
||||
type: Number,
|
||||
default: 78,
|
||||
},
|
||||
charlie: {
|
||||
}),
|
||||
charlie: new AttributeInfo({
|
||||
type: String,
|
||||
default: "Charlie",
|
||||
},
|
||||
delta: {
|
||||
}),
|
||||
delta: new AttributeInfo({
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
echo: {
|
||||
default: "echo",
|
||||
},
|
||||
foxtrot: {
|
||||
default: false,
|
||||
},
|
||||
golf: {
|
||||
default: [],
|
||||
},
|
||||
hotel: {
|
||||
}),
|
||||
echo: AttributeInfo.createValue("echo"),
|
||||
foxtrot: AttributeInfo.createValue(false),
|
||||
golf: AttributeInfo.createValue([]),
|
||||
hotel: new AttributeInfo({
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
india: {
|
||||
}),
|
||||
india: new AttributeInfo({
|
||||
type: [Number],
|
||||
default: () => [],
|
||||
},
|
||||
juliett: {
|
||||
}),
|
||||
juliett: new AttributeInfo({
|
||||
type: [String],
|
||||
default: ["a", "b", "c", "d", "e"],
|
||||
},
|
||||
kilo: {
|
||||
}),
|
||||
kilo: new AttributeInfo({
|
||||
type: [Boolean],
|
||||
default: () => [true, false, false, true, true],
|
||||
},
|
||||
lima: {
|
||||
type: String,
|
||||
},
|
||||
mike: {
|
||||
}),
|
||||
lima: AttributeInfo.createType(String),
|
||||
mike: new AttributeInfo({
|
||||
type: new Union(Number, String, Array),
|
||||
default: "Bar",
|
||||
},
|
||||
november: {
|
||||
}),
|
||||
november: new AttributeInfo({
|
||||
type: new Union(Number, String, Array),
|
||||
default: 0,
|
||||
},
|
||||
oscar: {
|
||||
}),
|
||||
oscar: new AttributeInfo({
|
||||
type: Entity1,
|
||||
default: () => new Entity1()
|
||||
},
|
||||
papa: {
|
||||
}),
|
||||
papa: new AttributeInfo({
|
||||
type: Entity1,
|
||||
default: () => new Entity1({ a: 12, b: 13 }),
|
||||
},
|
||||
quebec: {
|
||||
}),
|
||||
quebec: new AttributeInfo({
|
||||
default: 0, // will assign undefined because it does not satisfy the predicate
|
||||
predicate: v => v >= 1 && v <= 10,
|
||||
},
|
||||
romeo: {
|
||||
}),
|
||||
romeo: new AttributeInfo({
|
||||
type: Entity1,
|
||||
default: new Entity1(),
|
||||
inlined: true,
|
||||
},
|
||||
sierra: {
|
||||
}),
|
||||
sierra: new AttributeInfo({
|
||||
type: Entity2,
|
||||
default: new Entity2(),
|
||||
inlined: true,
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import Entity1 from "./Entity1.js"
|
||||
import Entity3 from "./Entity3.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
|
||||
export default class Entity4 extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
first: {
|
||||
first: new AttributeInfo({
|
||||
type: Entity3,
|
||||
default: new Entity3(),
|
||||
inlined: true,
|
||||
},
|
||||
second: {
|
||||
}),
|
||||
second: new AttributeInfo({
|
||||
default: [new Entity1({ a: 1, b: 2 }), new Entity1({ a: 11, b: 22 })],
|
||||
inlined: true,
|
||||
},
|
||||
}),
|
||||
third: new AttributeInfo({
|
||||
type: Array,
|
||||
default: null,
|
||||
})
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@@ -25,8 +30,4 @@ export default class Entity4 extends IEntity {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import EntityF from "./EntityF.js"
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import ObjectEntity from "../../js/entity/ObjectEntity.js"
|
||||
import EntityF from "./EntityF.js"
|
||||
|
||||
// @ts-expect-error
|
||||
export default class Entity5 extends ObjectEntity {
|
||||
|
||||
static attributes = {
|
||||
key1: {
|
||||
type: String,
|
||||
},
|
||||
key2: {
|
||||
type: EntityF,
|
||||
},
|
||||
}
|
||||
static {
|
||||
this.cleanupAttributes(this.attributes)
|
||||
key1: AttributeInfo.createType(String),
|
||||
key2: AttributeInfo.createType(EntityF),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import Grammar from "../../js/serialization/Grammar.js"
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import Union from "../../js/entity/Union.js"
|
||||
import Grammar from "../../js/serialization/Grammar.js"
|
||||
|
||||
export default class EntityF extends IEntity {
|
||||
|
||||
static lookbehind = new Union("Foo", "Bar")
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
arg1: {
|
||||
type: Number,
|
||||
},
|
||||
arg2: {
|
||||
type: String,
|
||||
},
|
||||
arg1: AttributeInfo.createType(Number),
|
||||
arg2: AttributeInfo.createType(String),
|
||||
lookbehind: new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: new Union("Foo", "Bar"),
|
||||
})
|
||||
}
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Configuration from "../../js/Configuration.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
import SVGIcon from "../../js/SVGIcon.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
|
||||
export default class EventNodes extends NodeTests {
|
||||
static {
|
||||
|
||||
102
tests/resources/IssuesNodes1.js
Normal file
102
tests/resources/IssuesNodes1.js
Normal file
@@ -0,0 +1,102 @@
|
||||
import Configuration from "../../js/Configuration.js"
|
||||
import Utility from "../../js/Utility.js"
|
||||
import { expect } from "../fixtures/test.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
|
||||
export default class IssuesNodes1 extends NodeTests {
|
||||
static {
|
||||
this.set([
|
||||
{
|
||||
name: "Issue 18",
|
||||
title: "Mask ( R )",
|
||||
value: String.raw`
|
||||
Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name="MaterialGraphNode_37" ExportPath="/Script/UnrealEd.MaterialGraphNode'/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_37'"
|
||||
Begin Object Class=/Script/Engine.MaterialExpressionComponentMask Name="MaterialExpressionComponentMask_0" ExportPath="/Script/Engine.MaterialExpressionComponentMask'/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_37.MaterialExpressionComponentMask_0'"
|
||||
End Object
|
||||
Begin Object Name="MaterialExpressionComponentMask_0" ExportPath="/Script/Engine.MaterialExpressionComponentMask'/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_37.MaterialExpressionComponentMask_0'"
|
||||
R=True
|
||||
MaterialExpressionEditorX=-544
|
||||
MaterialExpressionEditorY=32
|
||||
MaterialExpressionGuid=8EFA535CAE3A4DAF9DAE27B200E06EDC
|
||||
Material="/Script/UnrealEd.PreviewMaterial'/Engine/Transient.NewMaterial'"
|
||||
End Object
|
||||
MaterialExpression="/Script/Engine.MaterialExpressionComponentMask'MaterialExpressionComponentMask_0'"
|
||||
NodePosX=-544
|
||||
NodePosY=32
|
||||
AdvancedPinDisplay=Shown
|
||||
NodeGuid=54A40610EEC646A0954F310727D1B888
|
||||
CustomProperties Pin (PinId=DC3859AB4C8C12645EEA1AA4E500A637,PinName="Input",PinFriendlyName=NSLOCTEXT("MaterialGraphNode", "Space", " "),PinType.PinCategory="required",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=D5C8F4DF4AFE5EEB605ED382CD5744DE,PinName="R",PinType.PinCategory="optional",PinType.PinSubCategory="bool",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=7E43455B4D2232C4E99BB098631CAFCE,PinName="G",PinType.PinCategory="optional",PinType.PinSubCategory="bool",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=46CEC6754365CB39F9FC39944B40D5C6,PinName="B",PinType.PinCategory="optional",PinType.PinSubCategory="bool",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=F658E76C400B0AF242DFE292C92702C8,PinName="A",PinType.PinCategory="optional",PinType.PinSubCategory="bool",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=2EC8C8234D570AB2A03DB59A1FF65987,PinName="Output",PinFriendlyName=NSLOCTEXT("MaterialGraphNode", "Space", " "),Direction="EGPD_Output",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
End Object
|
||||
`,
|
||||
size: [7, 14.5],
|
||||
color: Configuration.nodeColors.green,
|
||||
icon: null,
|
||||
pins: 6,
|
||||
pinNames: Configuration.rgba,
|
||||
delegate: false,
|
||||
development: false,
|
||||
additionalTest: async (node, pins, blueprintPage) => {
|
||||
const relevantPins = (await Promise.all(
|
||||
pins.map(async p => {
|
||||
const innerText = await p.innerText()
|
||||
// @ts-expect-error
|
||||
return [Configuration.rgba.includes(innerText), p]
|
||||
})
|
||||
))
|
||||
.filter(([flag, value]) => flag)
|
||||
.map(([flag, value]) => /** @type {Locator<PinElement>} */(value))
|
||||
expect(await Promise.all(relevantPins.map(async pin => await pin.innerText()))).toStrictEqual(Configuration.rgba)
|
||||
for (const p of relevantPins) {
|
||||
const pinName = await p.innerText()
|
||||
expect(p.locator('input[type="checkbox"]')).toBeChecked({ checked: pinName === "R" })
|
||||
}
|
||||
await relevantPins[0].locator('input[type="checkbox"]').uncheck() // Uncheck "R"
|
||||
await relevantPins[2].locator('input[type="checkbox"]').check() // Check "B"
|
||||
await relevantPins[4].locator('input[type="checkbox"]').check() // Check "A"
|
||||
await relevantPins[2].locator('input[type="checkbox"]').uncheck() // Uncheck "B"
|
||||
await relevantPins[2].locator('input[type="checkbox"]').check() // Check "B"
|
||||
expect(node.locator(".ueb-node-name")).toHaveText("Mask ( B A )")
|
||||
const resultSerialization = await blueprintPage.blueprintLocator.evaluate(blueprint => {
|
||||
blueprint.selectAll()
|
||||
return blueprint.template.getCopyInputObject().getSerializedText()
|
||||
})
|
||||
const expectedSerialization = String.raw`
|
||||
Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name="MaterialGraphNode_37" ExportPath="/Script/UnrealEd.MaterialGraphNode'/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_37'"
|
||||
Begin Object Class=/Script/Engine.MaterialExpressionComponentMask Name="MaterialExpressionComponentMask_0" ExportPath="/Script/Engine.MaterialExpressionComponentMask'/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_37.MaterialExpressionComponentMask_0'"
|
||||
End Object
|
||||
Begin Object Name="MaterialExpressionComponentMask_0" ExportPath="/Script/Engine.MaterialExpressionComponentMask'/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_37.MaterialExpressionComponentMask_0'"
|
||||
B=True
|
||||
A=True
|
||||
MaterialExpressionEditorX=-544
|
||||
MaterialExpressionEditorY=32
|
||||
MaterialExpressionGuid=8EFA535CAE3A4DAF9DAE27B200E06EDC
|
||||
Material="/Script/UnrealEd.PreviewMaterial'/Engine/Transient.NewMaterial'"
|
||||
End Object
|
||||
MaterialExpression="/Script/Engine.MaterialExpressionComponentMask'MaterialExpressionComponentMask_0'"
|
||||
NodePosX=-544
|
||||
NodePosY=32
|
||||
AdvancedPinDisplay=Shown
|
||||
NodeGuid=54A40610EEC646A0954F310727D1B888
|
||||
CustomProperties Pin (PinId=DC3859AB4C8C12645EEA1AA4E500A637,PinName="Input",PinFriendlyName=NSLOCTEXT("MaterialGraphNode", "Space", " "),PinType.PinCategory="required",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=D5C8F4DF4AFE5EEB605ED382CD5744DE,PinName="R",PinType.PinCategory="optional",PinType.PinSubCategory="bool",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=7E43455B4D2232C4E99BB098631CAFCE,PinName="G",PinType.PinCategory="optional",PinType.PinSubCategory="bool",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=46CEC6754365CB39F9FC39944B40D5C6,PinName="B",PinType.PinCategory="optional",PinType.PinSubCategory="bool",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=F658E76C400B0AF242DFE292C92702C8,PinName="A",PinType.PinCategory="optional",PinType.PinSubCategory="bool",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=2EC8C8234D570AB2A03DB59A1FF65987,PinName="Output",PinFriendlyName=NSLOCTEXT("MaterialGraphNode", "Space", " "),Direction="EGPD_Output",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
End Object
|
||||
`
|
||||
const words = expectedSerialization
|
||||
.split("\n")
|
||||
.map(row => row.match(/\s*("?\w+(\s+\w+)*).+/)?.[1])
|
||||
.filter(v => v?.length > 0)
|
||||
expect(resultSerialization).toMatch(Utility.getFirstWordOrder(words))
|
||||
}
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { expect } from "../fixtures/test.js"
|
||||
import Configuration from "../../js/Configuration.js"
|
||||
import SVGIcon from "../../js/SVGIcon.js"
|
||||
import { expect } from "../fixtures/test.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
|
||||
export default class LegacyNodes extends NodeTests {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { expect } from "../fixtures/test.js"
|
||||
import Configuration from "../../js/Configuration.js"
|
||||
import IntegerEntity from "../../js/entity/IntegerEntity.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
import PinElement from "../../js/element/PinElement.js"
|
||||
import RBSerializationVector2DEntity from "../../js/entity/RBSerializationVector2DEntity.js"
|
||||
import Utility from "../../js/Utility.js"
|
||||
import PinElement from "../../js/element/PinElement.js"
|
||||
import IntegerEntity from "../../js/entity/IntegerEntity.js"
|
||||
import RBSerializationVector2DEntity from "../../js/entity/RBSerializationVector2DEntity.js"
|
||||
import VectorEntity from "../../js/entity/VectorEntity.js"
|
||||
import { expect } from "../fixtures/test.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
|
||||
export default class MaterialNodes extends NodeTests {
|
||||
static {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* delegate: Boolean,
|
||||
* development: Boolean,
|
||||
* variadic?: Boolean,
|
||||
* additionalTest?: (node: Locator<NodeElement>, pins: Locator<PinElement>[]) => void,
|
||||
* additionalTest?: (node: Locator<NodeElement>, pins: Locator<PinElement>[], blueprintPage: BlueprintFixture) => void,
|
||||
* }} TestData
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import SVGIcon from "../../js/SVGIcon.js"
|
||||
import PinElement from "../../js/element/PinElement.js"
|
||||
import { expect } from "../fixtures/test.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
import PinElement from "../../js/element/PinElement.js"
|
||||
import SVGIcon from "../../js/SVGIcon.js"
|
||||
|
||||
export default class OperationsNodes extends NodeTests {
|
||||
static {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Configuration from "../../js/Configuration.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
import SVGIcon from "../../js/SVGIcon.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
|
||||
export default class OtherNodes extends NodeTests {
|
||||
static {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { expect } from "../fixtures/test.js"
|
||||
import Configuration from "../../js/Configuration.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
import SVGIcon from "../../js/SVGIcon.js"
|
||||
import { expect } from "../fixtures/test.js"
|
||||
import NodeTests from "./NodeTests.js"
|
||||
|
||||
export default class PCGNodes extends NodeTests {
|
||||
static {
|
||||
|
||||
@@ -6,5 +6,6 @@ export default `{
|
||||
someBoolean2: False
|
||||
someObjectString: "gamma"
|
||||
someArray: (400,500,600,700,800,)
|
||||
someArray2: (400,500,600,700,800,)
|
||||
someEntity: Entity1(a=8, b=9)
|
||||
}`
|
||||
|
||||
@@ -24,5 +24,6 @@ export default `[[
|
||||
sierra.someBoolean2: False
|
||||
sierra.someObjectString: "gamma"
|
||||
sierra.someArray: (400,500,600,700,800,)
|
||||
sierra.someArray2: (400,500,600,700,800,)
|
||||
sierra.someEntity: Entity1(a=8, b=9)
|
||||
]]`
|
||||
|
||||
@@ -23,8 +23,10 @@ export default `Begin
|
||||
\${first.sierra.someBoolean2} => False
|
||||
\${first.sierra.someObjectString} => "gamma"
|
||||
\${first.sierra.someArray} => (400,500,600,700,800,)
|
||||
\${first.sierra.someArray2} => (400,500,600,700,800,)
|
||||
\${first.sierra.someEntity} => E1[A:8 - B:9]
|
||||
\${second(0).a} => 1
|
||||
\${second(0).b} => 2
|
||||
\${second(1)} => E1[A:11 - B:22]
|
||||
\${third} => ()
|
||||
End`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expect, test } from "./fixtures/test.js"
|
||||
import Utility from "../js/Utility.js"
|
||||
import { expect, test } from "./fixtures/test.js"
|
||||
|
||||
test.describe.configure({ mode: "parallel" })
|
||||
|
||||
|
||||
86
types.js
86
types.js
@@ -1,13 +1,3 @@
|
||||
/** @typedef {[Number, Number]} Coordinates */
|
||||
/**
|
||||
* @typedef {IEntity | String | Number | BigInt | Boolean | Array} TerminalAttribute
|
||||
* @typedef {TerminalAttribute | MirroredEntity<TerminalAttribute>} Attribute
|
||||
* @typedef {(
|
||||
* AttributeConstructor<Attribute> | AttributeConstructor<Attribute>[]
|
||||
* | MirroredEntity<Attribute> | Union | Union[] | ComputedType
|
||||
* )} AttributeTypeDescription
|
||||
* @typedef {(entity: IEntity) => Attribute} ValueSupplier
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {new (...args: any) => T} AnyConstructor
|
||||
@@ -15,7 +5,17 @@
|
||||
/**
|
||||
* @template {Attribute} T
|
||||
* @typedef {AnyConstructor<T> & EntityConstructor | StringConstructor | NumberConstructor | BigIntConstructor
|
||||
* | BooleanConstructor | ArrayConstructor | MirroredEntityConstructor<T>} AttributeConstructor
|
||||
* | BooleanConstructor | ArrayConstructor | MirroredEntityConstructor<T>} AttributeConstructor
|
||||
*/
|
||||
/**
|
||||
* @typedef {[Number, Number]} Coordinates
|
||||
* @typedef {IEntity | String | Number | BigInt | Boolean | Array} TerminalAttribute
|
||||
* @typedef {TerminalAttribute | MirroredEntity<TerminalAttribute>} Attribute
|
||||
* @typedef {(
|
||||
* AttributeConstructor<Attribute> | AttributeConstructor<Attribute>[]
|
||||
* | MirroredEntity<Attribute> | Union<any> | Union<any>[] | ComputedType
|
||||
* )} AttributeTypeDescription
|
||||
* @typedef {(entity: IEntity) => Attribute} ValueSupplier
|
||||
*/
|
||||
/**
|
||||
* @template {Attribute} T
|
||||
@@ -38,7 +38,9 @@
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {T extends StringConstructor
|
||||
* @typedef {T extends AnyConstructor<infer R>
|
||||
* ? R
|
||||
* : T extends StringConstructor
|
||||
* ? String
|
||||
* : T extends NumberConstructor
|
||||
* ? Number
|
||||
@@ -48,26 +50,40 @@
|
||||
* ? Boolean
|
||||
* : T extends ArrayConstructor
|
||||
* ? Array
|
||||
* : T extends MirroredEntity<infer R>
|
||||
* ? MirroredEntity<R>
|
||||
* : T extends AnyConstructor<infer R>
|
||||
* ? R
|
||||
* : any
|
||||
* } ConstructedType
|
||||
*/
|
||||
/**
|
||||
* @typedef {{
|
||||
* type?: AttributeTypeDescription,
|
||||
* default?: Attribute | ValueSupplier,
|
||||
* nullable?: Boolean,
|
||||
* ignored?: Boolean,
|
||||
* serialized?: Boolean,
|
||||
* expected?: Boolean,
|
||||
* inlined?: Boolean,
|
||||
* quoted?: Boolean,
|
||||
* predicate?: (value: Attribute) => Boolean,
|
||||
* }} AttributeInformation
|
||||
* @typedef {{ [key: String]: AttributeInformation }} AttributeDeclarations
|
||||
* @template T
|
||||
* @typedef {T extends [infer A] ? DescribedType<A>
|
||||
* : T extends [infer A, ...infer B] ? (DescribedType<A> | DescribedTypesFromArray<B>)
|
||||
* : any
|
||||
* } DescribedTypesFromArray
|
||||
**/
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {T extends AnyConstructor<infer R>
|
||||
* ? R
|
||||
* : T extends StringConstructor
|
||||
* ? String
|
||||
* : T extends NumberConstructor
|
||||
* ? Number
|
||||
* : T extends BigIntConstructor
|
||||
* ? BigInt
|
||||
* : T extends BooleanConstructor
|
||||
* ? Boolean
|
||||
* : T extends Array<infer R>
|
||||
* ? DescribedType<R>[]
|
||||
* : T extends MirroredEntity<infer R>
|
||||
* ? DescribedType<R>
|
||||
* : T extends Union<infer R>
|
||||
* ? DescribedTypesFromArray<R>
|
||||
* : T
|
||||
* } DescribedType
|
||||
*/
|
||||
/**
|
||||
* @typedef {import("./js/entity/AttributeInfo.js").default} AttributeInfo
|
||||
* @typedef {{ [key: String]: AttributeInfo }} AttributeDeclarations
|
||||
*/
|
||||
/**
|
||||
* @typedef {CustomEvent<{ value: Coordinates }>} UEBDragEvent
|
||||
@@ -82,6 +98,10 @@
|
||||
* (value: T): typeof value.constructor,
|
||||
* }} TypeGetter
|
||||
*/
|
||||
/**
|
||||
* @template {any[]} T
|
||||
* @typedef {import("./js/entity/Union.js").default<T>} Union
|
||||
*/
|
||||
/**
|
||||
* @typedef {typeof import("./js/Blueprint.js").default} BlueprintConstructor
|
||||
* @typedef {typeof import("./js/element/LinkElement.js").default} LinkElementConstructor
|
||||
@@ -141,7 +161,6 @@
|
||||
* @typedef {import("./js/entity/SimpleSerializationVectorEntity.js").default} SimpleSerializationVectorEntity
|
||||
* @typedef {import("./js/entity/SymbolEntity.js").default} SymbolEntity
|
||||
* @typedef {import("./js/entity/TerminalTypeEntity.js").default} TerminalTypeEntity
|
||||
* @typedef {import("./js/entity/Union.js").default} Union
|
||||
* @typedef {import("./js/entity/UnknownKeysEntity.js").default} UnknownKeysEntity
|
||||
* @typedef {import("./js/entity/UnknownPinEntity.js").default} UnknownPinEntity
|
||||
* @typedef {import("./js/entity/VariableReferenceEntity.js").default} VariableReferenceEntity
|
||||
@@ -191,6 +210,7 @@
|
||||
* @typedef {import("./js/template/SelectorTemplate.js").default} SelectorTemplate
|
||||
* @typedef {import("./js/template/window/ColorPickerWindowTemplate.js").default} ColorPickerWindowTemplate
|
||||
* @typedef {import("./js/template/window/WindowTemplate.js").default} WindowTemplate
|
||||
* @typedef {import ("./tests/fixtures/BlueprintFixture.js").default} BlueprintFixture
|
||||
* @typedef {import("lit").CSSResult} CSSResult
|
||||
* @typedef {import("lit").PropertyValues} PropertyValues
|
||||
* @typedef {import("lit").TemplateResult} TemplateResult
|
||||
@@ -210,7 +230,7 @@
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {{
|
||||
* evaluate<R, Arg>(pageFunction: (node: T, arg: Arg) => R, arg: Arg, options?: { timeout?: number }): Promise<R>
|
||||
* evaluate<R>(pageFunction: (node: T) => R, options?: { timeout?: number }): Promise<R>
|
||||
* } & import("@playwright/test").Locator} Locator
|
||||
*/
|
||||
* evaluate<R, Arg>(pageFunction: (node: T, arg: Arg) => R, arg: Arg, options?: { timeout?: number }): Promise<R>
|
||||
* evaluate<R>(pageFunction: (node: T) => R, options?: { timeout?: number }): Promise<R>
|
||||
* } & import("@playwright/test").Locator} Locator
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user