This commit is contained in:
barsdeveloper
2024-05-31 15:09:48 +02:00
parent 1c2778fbf8
commit ecc71b76d1
45 changed files with 1191 additions and 1078 deletions

View File

@@ -7,13 +7,20 @@ export default class AlternativesEntity extends IEntity {
/** @type {(typeof IEntity)[]} */
static alternatives = []
static className() {
let result = super.className()
if (this.alternatives.length) {
result += " (accepting: " + this.alternatives.map(v => v.className()).join(", ") + ")"
}
return result
}
static createGrammar() {
return this.alternatives
.map(entity => entity.grammar)
.reduce((acc, cur) => !cur || cur === Grammar.unknownValue || acc === Grammar.unknownValue
? Grammar.unknownValue
: P.alt(acc, cur)
)
const grammars = this.alternatives.map(entity => entity.grammar)
if (grammars.includes(Grammar.unknownValue)) {
return Grammar.unknownValue
}
return P.alt(...grammars)
}
/**

View File

@@ -7,21 +7,30 @@ export default class ArrayEntity extends IEntity {
/** @type {typeof IEntity} */
static type
static grammar = this.createGrammar()
/** @param {InstanceType<T>[]} values */
/** @param {ExtractType<T>[]} values */
constructor(values = []) {
super()
this.values = values
}
static createGrammar(elementGrammar = this.type.grammar) {
static createGrammar(elementGrammar = this.type?.grammar ?? P.lazy(() => Grammar.unknownValue)) {
return this.inlined
? elementGrammar
: P.seq(
P.reg(/\(\s*/),
elementGrammar.sepBy(Grammar.commaSeparation).opt(),
P.reg(/\s*(?:,\s*)?\)/),
).map(([_0, values, _3]) => new this(values instanceof Array ? values : []))
P.reg(/\s*(,\s*)?\)/, 1),
).map(([_0, values, trailing]) => {
let self = this
const hasTrailing = trailing !== undefined
if (hasTrailing !== self.trailing) {
self = self.flagTrailing(hasTrailing)
}
values = values instanceof Array ? values : []
return new self(values)
}).label(`ArrayEntity of ${this.type?.className() ?? "unknown values"}`)
}
/**
@@ -29,8 +38,10 @@ export default class ArrayEntity extends IEntity {
* @param {NonNullable<T>} type
*/
static of(type) {
const result = /** @type {(typeof ArrayEntity<T>) & { type: T }} */(this.asUniqueClass())
result.type = type
const result = /** @type {typeof ArrayEntity<T> & { type: ExtractType<T>, grammar: P<ArrayEntity<T>> }} */(
this.asUniqueClass()
)
result.type = /** @type {ExtractType<T>} */(type)
this.grammar = result.createGrammar()
return result
}

View File

@@ -56,18 +56,18 @@ export default class BlueprintEntity extends ObjectEntity {
/** @param {ObjectEntity} entity */
mergeWith(entity) {
if (!entity.ScriptVariables || entity.ScriptVariables.length === 0) {
if (!entity.ScriptVariables || entity.ScriptVariables.values.length === 0) {
return this
}
if (!this.ScriptVariables || this.ScriptVariables.length === 0) {
if (!this.ScriptVariables || this.ScriptVariables.values.length === 0) {
this.ScriptVariables = entity.ScriptVariables
}
let scriptVariables = Utility.mergeArrays(
this.ScriptVariables,
entity.ScriptVariables,
this.ScriptVariables.values,
entity.ScriptVariables.values,
(l, r) => l.OriginalChangeId.value == r.OriginalChangeId.value
)
if (scriptVariables.length === this.ScriptVariables.length) {
if (scriptVariables.length === this.ScriptVariables.values.length) {
return this
}
const entries = scriptVariables.concat(scriptVariables).map((v, i) => {

View File

@@ -3,7 +3,9 @@ import IEntity from "./IEntity.js"
export default class BooleanEntity extends IEntity {
static grammar = P.regArray(/(true)|false/i).map(v => v[1] ? new this(true) : new this(false))
static grammar = P.regArray(/(true)|false/i)
.map(v => v[1] ? new this(true) : new this(false))
.label("BooleanEntity")
constructor(value = false) {
super()
@@ -14,7 +16,13 @@ export default class BooleanEntity extends IEntity {
return this.value
}
toString() {
return this.value.toString()
toString(insideString = false) {
return this.value
? insideString
? "true"
: "True"
: insideString
? "false"
: "False"
}
}

View File

@@ -1,15 +1,15 @@
import P from "parsernostrum"
import IEntity from "./IEntity.js"
import IPrintableEntity from "./IPrintableEntity.js"
import InvariantTextEntity from "./InvariantTextEntity.js"
import LocalizedTextEntity from "./LocalizedTextEntity.js"
import StringEntity from "./StringEntity.js"
export default class FormatTextEntity extends IEntity {
export default class FormatTextEntity extends IPrintableEntity {
static lookbehind = ["LOCGEN_FORMAT_NAMED", "LOCGEN_FORMAT_ORDERED"]
static grammar = P.seq(
// Resulting regex: /(LOCGEN_FORMAT_NAMED|LOCGEN_FORMAT_ORDERED)\s*/
P.reg(new RegExp(String.raw`(${this.lookbehind.reduce((acc, cur) => acc + "|" + cur)})\s*\(\s*)`), 1),
P.reg(new RegExp(String.raw`(${this.lookbehind.reduce((acc, cur) => acc + "|" + cur)})\s*`), 1),
P.alt(
...[StringEntity, LocalizedTextEntity, InvariantTextEntity, FormatTextEntity].map(type => type.grammar)
).sepBy(P.reg(/\s*\,\s*/)),
@@ -20,6 +20,7 @@ export default class FormatTextEntity extends IEntity {
result.lookbehind = lookbehind
return result
})
.label("FormatTextEntity")
/** @param {(StringEntity | LocalizedTextEntity | InvariantTextEntity | FormatTextEntity)[]} values */
constructor(values) {
@@ -27,20 +28,21 @@ export default class FormatTextEntity extends IEntity {
this.values = values
}
toString() {
print() {
const pattern = this.values?.[0]?.toString() // The pattern is always the first element of the array
if (!pattern) {
return ""
}
const values = this.values.slice(1).map(v => v.toString())
return this.lookbehind == "LOCGEN_FORMAT_NAMED"
let result = this.Self().lookbehind == "LOCGEN_FORMAT_NAMED"
? pattern.replaceAll(/\{([a-zA-Z]\w*)\}/g, (substring, arg) => {
const argLocation = values.indexOf(arg) + 1
return argLocation > 0 && argLocation < values.length
? values[argLocation]
: substring
})
: this.lookbehind == "LOCGEN_FORMAT_ORDERED"
: this.Self().lookbehind == "LOCGEN_FORMAT_ORDERED"
? pattern.replaceAll(/\{(\d+)\}/g, (substring, arg) => {
const argValue = Number(arg)
return argValue < values.length
@@ -48,5 +50,6 @@ export default class FormatTextEntity extends IEntity {
: substring
})
: ""
result = this.Self().lookbehind + "(" + result + ")"
}
}

View File

@@ -16,8 +16,8 @@ export default class FunctionReferenceEntity extends IEntity {
constructor(values) {
super(values)
/** @type {ObjectReferenceEntity} */ this.MemberParent
/** @type {String} */ this.MemberName
/** @type {GuidEntity} */ this.MemberGuid
/** @type {InstanceType<typeof FunctionReferenceEntity.attributes.MemberParent>} */ this.MemberParent
/** @type {InstanceType<typeof FunctionReferenceEntity.attributes.MemberName>} */ this.MemberName
/** @type {InstanceType<typeof FunctionReferenceEntity.attributes.MemberGuid>} */ this.MemberGuid
}
}

View File

@@ -10,7 +10,7 @@ if (typeof window === "undefined") {
export default class GuidEntity extends IEntity {
static grammar = P.reg(/[0-9a-fA-F]{32}/).map(v => new this(v))
static grammar = P.reg(/[0-9A-F]{32}/i).map(v => new this(v)).label("GuidEntity")
static generateGuid() {
let values = new Uint32Array(4)

View File

@@ -10,45 +10,22 @@ export default class IEntity {
/** @type {(entity: Attribute, serialized: String) => String} */
static notWrapped = (entity, serialized) => serialized
/** @type {(entity: Attribute, serialized: String) => String} */
static bracketsWrapped = (entity, serialized) => `(${serialized})`
/** @type {(entity: IEntity, serialized: String) => String} */
static defaultWrapped = (entity, serialized) => `${entity.lookbehind}(${serialized})`
static wrap = this.notWrapped
static wrap = this.defaultWrapped
static attributeSeparator = ","
static trailingSeparator = false
/** @type {(k: String) => String} */
static printKey = k => k
/** @type {P<Parser>} */
static grammar = P.failure()
/** @type {P<InstanceType<typeof this>>} */
static grammar = /** @type {any} */(P.failure())
/** @type {{ [key: String]: typeof IEntity }} */
static attributes = {}
/** @type {String | String[]} */
static lookbehind = ""
/** @type {typeof IEntity.lookbehind} */
#lookbehind = this.Self().lookbehind
get lookbehind() {
return this.#lookbehind
}
set lookbehind(value) {
throw this.#lookbehind = value
}
/** @type {String[]} */
#keys
get keys() {
return this.#keys ?? Object.keys(this.Self().attributes)
}
set keys(value) {
this.#keys = [... new Set(value)]
}
/** @type {(type: typeof IEntity) => InstanceType<typeof IEntity>} */
static default
static nullable = false
@@ -58,10 +35,30 @@ export default class IEntity {
static inlined = false // The key is a subobject or array and printed as inlined (A.B=123, A(0)=123)
static quoted = false // Key is serialized with quotes
static silent = false // Do not serialize if default
static uninitialized = false // Do not initialize with default
static trailing = false // Add attribute separator after the last attribute when serializing
/** @type {String | String[]} */
static lookbehind = ""
#lookbehind = /** @type {String} */(this.Self().lookbehind)
get lookbehind() {
return this.#lookbehind
}
set lookbehind(value) {
this.#lookbehind = value
}
/** @type {String[]} */
#keys
get keys() {
return this.#keys ?? Object.keys(this)
}
set keys(value) {
this.#keys = [... new Set(value)]
}
constructor(values = {}) {
const keys = Utility.mergeArrays(Object.keys(values.attributes), Object.keys(this.Self().attributes))
const keys = Utility.mergeArrays(Object.keys(values), Object.keys(this.Self().attributes))
for (const key of keys) {
if (values[key] !== undefined) {
this[key] = values[key]
@@ -75,6 +72,14 @@ export default class IEntity {
}
}
static className() {
let self = this
while (!self.name) {
self = Object.getPrototypeOf(self)
}
return self.name
}
/** @param {String} key */
showProperty(key) {
/** @type {IEntity} */
@@ -104,6 +109,17 @@ export default class IEntity {
return this
}
/**
* @template {typeof IEntity} T
* @this {T}
* @param {String} value
*/
static withLookbehind(value) {
const result = this.asUniqueClass()
result.lookbehind = value
return result
}
/**
* @template {typeof IEntity} T
* @this {T}
@@ -144,6 +160,16 @@ export default class IEntity {
return result
}
/**
* @template {typeof IEntity} T
* @this {T}
*/
static flagQuoted(value = true) {
const result = this.asUniqueClass()
result.quoted = value
return result
}
/**
* @template {typeof IEntity} T
* @this {T}
@@ -154,6 +180,16 @@ export default class IEntity {
return result
}
/**
* @template {typeof IEntity} T
* @this {T}
*/
static flagTrailing(value = true) {
const result = this.asUniqueClass()
result.trailing = value
return result
}
/**
* @template {typeof IEntity} T
* @this {InstanceType<T>}
@@ -206,6 +242,9 @@ export default class IEntity {
if (thisKeys.length != otherKeys.length) {
return false
}
if (this.valueOf && other.valueOf) {
return this.valueOf() === other.valueOf()
}
for (let i = 0; i < thisKeys.length; ++i) {
if (!(this[thisKeys[i]] instanceof IEntity && this[thisKeys[i]].equals(other[otherKeys[i]]))) {
return false
@@ -250,7 +289,7 @@ export default class IEntity {
}
result += serialization
}
if (Self.trailingSeparator && result.length) {
if (Self.trailing && result.length) {
result += Self.attributeSeparator
}
return Self.wrap(this, result)

View File

@@ -0,0 +1,8 @@
import IEntity from "./IEntity.js"
export default class IPrintableEntity extends IEntity {
print() {
return this.toString()
}
}

View File

@@ -1,7 +1,6 @@
import P from "parsernostrum"
import NumberEntity from "./NumberEntity.js"
// @ts-expect-error
export default class IntegerEntity extends NumberEntity {
static grammar = P.numberInteger.map(v => new this(v))

View File

@@ -1,25 +1,39 @@
import P from "parsernostrum"
import IEntity from "./IEntity.js"
import Parsernostrum from "parsernostrum"
import IPrintableEntity from "./IPrintableEntity.js"
export default class InvariantTextEntity extends IEntity {
export default class InvariantTextEntity extends IPrintableEntity {
static lookbehind = "INVTEXT"
static grammar = P.alt(
P.seq(
P.reg(new RegExp(`${this.lookbehind}\\s*\\(`)),
P.doubleQuotedString,
P.reg(/\s*\)/)
).map(([_0, value, _2]) => new this(value)),
P.reg(new RegExp(this.lookbehind)).map(() => new this()) // InvariantTextEntity can not have arguments
).map(value => new this(value))
static grammar = Parsernostrum.alt(
Parsernostrum.seq(
Parsernostrum.reg(new RegExp(`${this.lookbehind}\\s*\\(`)),
Parsernostrum.doubleQuotedString,
Parsernostrum.reg(/\s*\)/)
).map(([_0, value, _2]) => Number(value)),
Parsernostrum.reg(new RegExp(this.lookbehind)).map(() => 0) // InvariantTextEntity can not have arguments
)
.map(value => new this(value))
.label("InvariantTextEntity")
constructor(value = "") {
super()
this.value = value
}
toString() {
print() {
let xxxx = Parsernostrum.alt(
Parsernostrum.seq(
Parsernostrum.reg(new RegExp(`${this.lookbehind}\\s*\\(`)),
Parsernostrum.doubleQuotedString,
Parsernostrum.reg(/\s*\)/)
).map(([_0, value, _2]) => Number(value)),
Parsernostrum.reg(new RegExp(this.lookbehind)).map(() => 0) // InvariantTextEntity can not have arguments
)
return this.value
}
toString() {
return this.lookbehind + "(" + this.value + ")"
}
}

View File

@@ -27,11 +27,11 @@ export default class KeyBindingEntity extends IEntity {
constructor() {
super()
/** @type {String} */ this.ActionName
/** @type {Boolean} */ this.bShift
/** @type {Boolean} */ this.bCtrl
/** @type {Boolean} */ this.bAlt
/** @type {Boolean} */ this.bCmd
/** @type {IdentifierEntity} */ this.Key
/** @type {InstanceType<typeof KeyBindingEntity.attributes.ActionName>} */ this.ActionName
/** @type {InstanceType<typeof KeyBindingEntity.attributes.bShift>} */ this.bShift
/** @type {InstanceType<typeof KeyBindingEntity.attributes.bCtrl>} */ this.bCtrl
/** @type {InstanceType<typeof KeyBindingEntity.attributes.bAlt>} */ this.bAlt
/** @type {InstanceType<typeof KeyBindingEntity.attributes.bCmd>} */ this.bCmd
/** @type {InstanceType<typeof KeyBindingEntity.attributes.Key>} */ this.Key
}
}

View File

@@ -14,7 +14,7 @@ export default class LinearColorEntity extends IEntity {
B: ColorChannelEntity.withDefault(),
A: ColorChannelEntity.withDefault(type => new type(1)),
}
static grammar = Grammar.createEntityGrammar(this, false)
static grammar = Grammar.createEntityGrammar(this).label("LinearColorEntity")
#H = new ColorChannelEntity()
get H() {
@@ -26,18 +26,35 @@ export default class LinearColorEntity extends IEntity {
#S = new ColorChannelEntity()
get S() {
return this.#H
return this.#S
}
set S(value) {
this.#H = value
this.#S = value
}
#V = new ColorChannelEntity()
get V() {
return this.#H
return this.#V
}
set V(value) {
this.#H = value
this.#V = value
}
constructor(values) {
super(values)
if (values instanceof Array) {
values = {
R: values[0] ?? 0,
G: values[1] ?? 0,
B: values[2] ?? 0,
A: values[3] ?? 1,
}
}
/** @type {InstanceType<typeof LinearColorEntity.attributes.R>} */ this.R
/** @type {InstanceType<typeof LinearColorEntity.attributes.G>} */ this.G
/** @type {InstanceType<typeof LinearColorEntity.attributes.B>} */ this.B
/** @type {InstanceType<typeof LinearColorEntity.attributes.A>} */ this.A
this.#updateHSV()
}
/** @param {Number} x */
@@ -129,23 +146,6 @@ export default class LinearColorEntity extends IEntity {
)
}
constructor(values) {
super(values)
if (values instanceof Array) {
values = {
R: values[0] ?? 0,
G: values[1] ?? 0,
B: values[2] ?? 0,
A: values[3] ?? 1,
}
}
/** @type {ColorChannelEntity} */ this.R
/** @type {ColorChannelEntity} */ this.G
/** @type {ColorChannelEntity} */ this.B
/** @type {ColorChannelEntity} */ this.A
this.#updateHSV()
}
#updateHSV() {
const r = this.R.value
const g = this.G.value
@@ -311,8 +311,4 @@ export default class LinearColorEntity extends IEntity {
toArray() {
return [this.R.value, this.G.value, this.B.value, this.A.value]
}
toString() {
return Utility.printLinearColor(this)
}
}

View File

@@ -1,24 +1,27 @@
import P from "parsernostrum"
import Utility from "../Utility.js"
import Grammar from "../serialization/Grammar.js"
import IEntity from "./IEntity.js"
import IPrintableEntity from "./IPrintableEntity.js"
export default class LocalizedTextEntity extends IEntity {
export default class LocalizedTextEntity extends IPrintableEntity {
static lookbehind = "NSLOCTEXT"
static grammar = P.regArray(new RegExp(
String.raw`${this.attributes.lookbehind.default}\s*\(`
String.raw`${this.lookbehind}\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*`
+ String.raw`(?:,\s+)?`
+ String.raw`(,\s+)?`
+ String.raw`\)`,
"m"
)).map(matchResult => new this(
Utility.unescapeString(matchResult[1]),
Utility.unescapeString(matchResult[2]),
Utility.unescapeString(matchResult[3]),
))
)).map(matchResult => {
const self = matchResult[4] ? this.flagTrailing() : this
return new self(
Utility.unescapeString(matchResult[1]),
Utility.unescapeString(matchResult[2]),
Utility.unescapeString(matchResult[3]),
)
}).label("LocalizedTextEntity")
#namespace
get namespace() {
@@ -44,7 +47,6 @@ export default class LocalizedTextEntity extends IEntity {
this.#value = value
}
constructor(namespace = "", key = "", value = "") {
super()
this.namespace = namespace
@@ -52,7 +54,12 @@ export default class LocalizedTextEntity extends IEntity {
this.value = value
}
toString() {
print() {
return Utility.capitalFirstLetter(this.value)
}
toString() {
const trailer = this.Self().trailing ? ", " : ""
return `${this.lookbehind}(${this.namespace}, ${this.key}, ${this.value}${trailer})`
}
}

View File

@@ -15,9 +15,9 @@ export default class MacroGraphReferenceEntity extends IEntity {
constructor(values) {
super(values)
/** @type {ObjectReferenceEntity} */ this.MacroGraph
/** @type {ObjectReferenceEntity} */ this.GraphBlueprint
/** @type {GuidEntity} */ this.GuidEntity
/** @type {InstanceType<typeof MacroGraphReferenceEntity.attributes.MacroGraph>} */ this.MacroGraph
/** @type {InstanceType<typeof MacroGraphReferenceEntity.attributes.GraphBlueprint>} */ this.GraphBlueprint
/** @type {InstanceType<typeof MacroGraphReferenceEntity.attributes.GraphGuid>} */ this.GraphGuid
}
getMacroName() {

View File

@@ -6,7 +6,7 @@ export default class MirroredEntity extends IEntity {
/** @type {typeof IEntity} */
static type
/** @param {() => T} getter */
/** @param {() => InstanceType<T>} getter */
constructor(getter = null) {
super()
this.getter = getter
@@ -32,7 +32,11 @@ export default class MirroredEntity extends IEntity {
return result
}
toString() {
return this.getter().toString()
toString(
insideString = false,
indentation = "",
printKey = this.Self().printKey,
) {
return this.getter().toString(insideString, indentation, printKey)
}
}

View File

@@ -1,13 +1,14 @@
import P from "parsernostrum"
import Grammar from "../serialization/Grammar.js"
import IEntity from "./IEntity.js"
export default class NumberEntity extends IEntity {
static grammar = P.regArray(
new RegExp(`(${P.number.getParser().parser.regexp.source})|(\\+?inf)|(-inf)`)
new RegExp(`(${Grammar.numberRegexSource})|(\\+?inf)|(-inf)`)
).map(([_0, n, plusInf, minusInf]) => new this(
n ? Number(n) : plusInf ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY
))
)).label("NumberEntity")
/** @type {Number} */
#value
@@ -31,6 +32,12 @@ export default class NumberEntity extends IEntity {
}
toString() {
if (this.value === Number.POSITIVE_INFINITY) {
return "+inf"
}
if (this.value === Number.NEGATIVE_INFINITY) {
return "-inf"
}
return this.value.toString()
}
}

View File

@@ -28,12 +28,14 @@ import VariableReferenceEntity from "./VariableReferenceEntity.js"
export default class ObjectEntity extends IEntity {
#_exported = false
get _exported() {
return this.#_exported
static trailing = true
#exported = false
get exported() {
return this.#exported
}
set _exported(value) {
this.#_exported = value
set exported(value) {
this.#exported = value
}
static attributes = {
@@ -130,7 +132,7 @@ export default class ObjectEntity extends IEntity {
ScriptVariables: ArrayEntity.of(ScriptVariableEntity),
Node: MirroredEntity.of(ObjectReferenceEntity),
ExportedNodes: StringEntity,
CustomProperties: ArrayEntity.of(AlternativesEntity.accepting(PinEntity, UnknownPinEntity)),
CustomProperties: ArrayEntity.of(AlternativesEntity.accepting(PinEntity, UnknownPinEntity)).withDefault().flagSilent(),
}
static #nameRegex = /^(\w+?)(?:_(\d+))?$/
static customPropertyGrammar = P.seq(
@@ -144,28 +146,28 @@ export default class ObjectEntity extends IEntity {
Grammar.symbolQuoted.map(v => [v, true]),
Grammar.symbol.map(v => [v, false]),
),
P.reg(
new RegExp(`\\s*\\(\\s*(\\d+)\\s*\\)\\s*\\=\\s*`),
1
).map(Number)
P.reg(new RegExp(String.raw`\s*\(\s*(\d+)\s*\)\s*\=\s*`), 1).map(Number)
)
.chain(
/** @param {[[String, Boolean], Number]} param */
/** @param {[[keyof ObjectEntity.attributes, Boolean], Number]} param */
([[symbol, quoted], index]) =>
Grammar.grammarFor(this.attributes[symbol])
.map(currentValue =>
values => {
(values[symbol] ??= [])[index] = currentValue
Utility.objectSet(values, ["attributes", symbol, "quoted"], quoted)
if (!this.attributes[symbol]?.inlined) {
if (!values.attributes) {
IEntity.defineAttributes(values, {})
}
Utility.objectSet(values, ["attributes", symbol, "type"], [currentValue.constructor])
Utility.objectSet(values, ["attributes", symbol, "inlined"], true)
this.attributes[symbol].grammar.map(currentValue =>
values => {
if (values[symbol] === undefined) {
let arrayEntity = ArrayEntity
if (quoted != arrayEntity.quoted) {
arrayEntity = arrayEntity.flagQuoted(quoted)
}
if (!arrayEntity.inlined) {
arrayEntity = arrayEntity.flagInlined()
}
values[symbol] = new arrayEntity()
}
)
/** @type {ArrayEntity} */
const target = values[symbol]
target.values[index] = currentValue
}
)
)
static grammar = this.createGrammar()
@@ -233,73 +235,71 @@ export default class ObjectEntity extends IEntity {
super(values)
// Attributes
/** @type {(PinEntity | UnknownPinEntity)[]} */ this.CustomProperties
/** @type {Boolean} */ this.bIsPureFunc
/** @type {Boolean} */ this.isExported
/** @type {FunctionReferenceEntity} */ this.ComponentPropertyName
/** @type {FunctionReferenceEntity} */ this.EventReference
/** @type {FunctionReferenceEntity} */ this.FunctionReference
/** @type {IdentifierEntity} */ this.AdvancedPinDisplay
/** @type {IdentifierEntity} */ this.EnabledState
/** @type {IntegerEntity} */ this.NodeHeight
/** @type {IntegerEntity} */ this.NodePosX
/** @type {IntegerEntity} */ this.NodePosY
/** @type {IntegerEntity} */ this.NodeWidth
/** @type {LinearColorEntity} */ this.CommentColor
/** @type {LinearColorEntity} */ this.NodeTitleColor
/** @type {MacroGraphReferenceEntity} */ this.MacroGraphReference
/** @type {MirroredEntity} */ this.MaterialExpressionEditorX
/** @type {MirroredEntity} */ this.MaterialExpressionEditorY
/** @type {MirroredEntity} */ this.SizeX
/** @type {MirroredEntity} */ this.SizeY
/** @type {MirroredEntity} */ this.Text
/** @type {MirroredEntity<IntegerEntity>} */ this.PositionX
/** @type {MirroredEntity<IntegerEntity>} */ this.PositionY
/** @type {MirroredEntity<ObjectReferenceEntity>} */ this.Node
/** @type {null[]} */ this.PinTags
/** @type {Number} */ this.NumAdditionalInputs
/** @type {ObjectReferenceEntity[]} */ this.InputPins
/** @type {ObjectReferenceEntity[]} */ this.OutputPins
/** @type {ObjectReferenceEntity} */ this.Archetype
/** @type {ObjectReferenceEntity} */ this.BlueprintElementInstance
/** @type {ObjectReferenceEntity} */ this.BlueprintElementType
/** @type {ObjectReferenceEntity} */ this.Class
/** @type {ObjectReferenceEntity} */ this.Enum
/** @type {ObjectReferenceEntity} */ this.ExportPath
/** @type {ObjectReferenceEntity} */ this.FunctionScript
/** @type {ObjectReferenceEntity} */ this.Graph
/** @type {ObjectReferenceEntity} */ this.MaterialExpression
/** @type {ObjectReferenceEntity} */ this.MaterialExpressionComment
/** @type {ObjectReferenceEntity} */ this.MaterialFunction
/** @type {ObjectReferenceEntity} */ this.ObjectRef
/** @type {ObjectReferenceEntity} */ this.PCGNode
/** @type {ObjectReferenceEntity} */ this.SettingsInterface
/** @type {ObjectReferenceEntity} */ this.StructType
/** @type {ObjectReferenceEntity} */ this.TargetType
/** @type {ScriptVariableEntity[]} */ this.ScriptVariables
/** @type {String[]} */ this.EnumEntries
/** @type {String[]} */ this.PinNames
/** @type {String} */ this.CustomFunctionName
/** @type {String} */ this.DelegatePropertyName
/** @type {String} */ this.ExportedNodes
/** @type {String} */ this.FunctionDisplayName
/** @type {String} */ this.InputName
/** @type {String} */ this.Name
/** @type {String} */ this.NodeComment
/** @type {String} */ this.NodeTitle
/** @type {String} */ this.Operation
/** @type {String} */ this.OpName
/** @type {String} */ this.ProxyFactoryFunctionName
/** @type {String} */ this.SubgraphInstance
/** @type {String} */ this.Text
/** @type {SymbolEntity} */ this.AxisKey
/** @type {SymbolEntity} */ this.HiGenGridSize
/** @type {SymbolEntity} */ this.InputAxisKey
/** @type {SymbolEntity} */ this.InputKey
/** @type {SymbolEntity} */ this.InputType
/** @type {UnknownPinEntity[]} */ this.AddedPins
/** @type {VariableReferenceEntity} */ this.DelegateReference
/** @type {VariableReferenceEntity} */ this.VariableReference
/** @type {InstanceType<typeof ObjectEntity.attributes.AddedPins>} */ this.AddedPins
/** @type {InstanceType<typeof ObjectEntity.attributes.AdvancedPinDisplay>} */ this.AdvancedPinDisplay
/** @type {InstanceType<typeof ObjectEntity.attributes.Archetype>} */ this.Archetype
/** @type {InstanceType<typeof ObjectEntity.attributes.AxisKey>} */ this.AxisKey
/** @type {InstanceType<typeof ObjectEntity.attributes.bIsPureFunc>} */ this.bIsPureFunc
/** @type {InstanceType<typeof ObjectEntity.attributes.BlueprintElementInstance>} */ this.BlueprintElementInstance
/** @type {InstanceType<typeof ObjectEntity.attributes.BlueprintElementType>} */ this.BlueprintElementType
/** @type {InstanceType<typeof ObjectEntity.attributes.Class>} */ this.Class
/** @type {InstanceType<typeof ObjectEntity.attributes.CommentColor>} */ this.CommentColor
/** @type {InstanceType<typeof ObjectEntity.attributes.ComponentPropertyName>} */ this.ComponentPropertyName
/** @type {InstanceType<typeof ObjectEntity.attributes.CustomFunctionName>} */ this.CustomFunctionName
/** @type {InstanceType<typeof ObjectEntity.attributes.CustomProperties>} */ this.CustomProperties
/** @type {InstanceType<typeof ObjectEntity.attributes.DelegatePropertyName>} */ this.DelegatePropertyName
/** @type {InstanceType<typeof ObjectEntity.attributes.DelegateReference>} */ this.DelegateReference
/** @type {InstanceType<typeof ObjectEntity.attributes.EnabledState>} */ this.EnabledState
/** @type {InstanceType<typeof ObjectEntity.attributes.Enum>} */ this.Enum
/** @type {InstanceType<typeof ObjectEntity.attributes.EnumEntries>} */ this.EnumEntries
/** @type {InstanceType<typeof ObjectEntity.attributes.EventReference>} */ this.EventReference
/** @type {InstanceType<typeof ObjectEntity.attributes.ExportedNodes>} */ this.ExportedNodes
/** @type {InstanceType<typeof ObjectEntity.attributes.ExportPath>} */ this.ExportPath
/** @type {InstanceType<typeof ObjectEntity.attributes.FunctionDisplayName>} */ this.FunctionDisplayName
/** @type {InstanceType<typeof ObjectEntity.attributes.FunctionReference>} */ this.FunctionReference
/** @type {InstanceType<typeof ObjectEntity.attributes.FunctionScript>} */ this.FunctionScript
/** @type {InstanceType<typeof ObjectEntity.attributes.Graph>} */ this.Graph
/** @type {InstanceType<typeof ObjectEntity.attributes.HiGenGridSize>} */ this.HiGenGridSize
/** @type {InstanceType<typeof ObjectEntity.attributes.InputAxisKey>} */ this.InputAxisKey
/** @type {InstanceType<typeof ObjectEntity.attributes.InputKey>} */ this.InputKey
/** @type {InstanceType<typeof ObjectEntity.attributes.InputName>} */ this.InputName
/** @type {InstanceType<typeof ObjectEntity.attributes.InputPins>} */ this.InputPins
/** @type {InstanceType<typeof ObjectEntity.attributes.InputType>} */ this.InputType
/** @type {InstanceType<typeof ObjectEntity.attributes.MacroGraphReference>} */ this.MacroGraphReference
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialExpression>} */ this.MaterialExpression
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialExpressionComment>} */ this.MaterialExpressionComment
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialExpressionEditorX>} */ this.MaterialExpressionEditorX
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialExpressionEditorY>} */ this.MaterialExpressionEditorY
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialFunction>} */ this.MaterialFunction
/** @type {InstanceType<typeof ObjectEntity.attributes.Name>} */ this.Name
/** @type {InstanceType<typeof ObjectEntity.attributes.Node>} */ this.Node
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeComment>} */ this.NodeComment
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeHeight>} */ this.NodeHeight
/** @type {InstanceType<typeof ObjectEntity.attributes.NodePosX>} */ this.NodePosX
/** @type {InstanceType<typeof ObjectEntity.attributes.NodePosY>} */ this.NodePosY
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeTitle>} */ this.NodeTitle
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeTitleColor>} */ this.NodeTitleColor
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeWidth>} */ this.NodeWidth
/** @type {InstanceType<typeof ObjectEntity.attributes.NumAdditionalInputs>} */ this.NumAdditionalInputs
/** @type {InstanceType<typeof ObjectEntity.attributes.ObjectRef>} */ this.ObjectRef
/** @type {InstanceType<typeof ObjectEntity.attributes.Operation>} */ this.Operation
/** @type {InstanceType<typeof ObjectEntity.attributes.OpName>} */ this.OpName
/** @type {InstanceType<typeof ObjectEntity.attributes.OutputPins>} */ this.OutputPins
/** @type {InstanceType<typeof ObjectEntity.attributes.PCGNode>} */ this.PCGNode
/** @type {InstanceType<typeof ObjectEntity.attributes.PinNames>} */ this.PinNames
/** @type {InstanceType<typeof ObjectEntity.attributes.PositionX>} */ this.PositionX
/** @type {InstanceType<typeof ObjectEntity.attributes.PositionY>} */ this.PositionY
/** @type {InstanceType<typeof ObjectEntity.attributes.ProxyFactoryFunctionName>} */ this.ProxyFactoryFunctionName
/** @type {InstanceType<typeof ObjectEntity.attributes.ScriptVariables>} */ this.ScriptVariables
/** @type {InstanceType<typeof ObjectEntity.attributes.SettingsInterface>} */ this.SettingsInterface
/** @type {InstanceType<typeof ObjectEntity.attributes.SizeX>} */ this.SizeX
/** @type {InstanceType<typeof ObjectEntity.attributes.SizeY>} */ this.SizeY
/** @type {InstanceType<typeof ObjectEntity.attributes.StructType>} */ this.StructType
/** @type {InstanceType<typeof ObjectEntity.attributes.SubgraphInstance>} */ this.SubgraphInstance
/** @type {InstanceType<typeof ObjectEntity.attributes.TargetType>} */ this.TargetType
/** @type {InstanceType<typeof ObjectEntity.attributes.Text>} */ this.Text
/** @type {InstanceType<typeof ObjectEntity.attributes.Text>} */ this.Text
/** @type {InstanceType<typeof ObjectEntity.attributes.VariableReference>} */ this.VariableReference
// Legacy nodes pins
if (this["Pins"] instanceof Array) {
@@ -481,10 +481,7 @@ export default class ObjectEntity extends IEntity {
}
getCustomproperties(canCreate = false) {
if (canCreate && !this.CustomProperties) {
this.CustomProperties = []
}
return this.CustomProperties ?? []
return this.CustomProperties.values
}
/** @returns {PinEntity[]} */
@@ -615,4 +612,44 @@ export default class ObjectEntity extends IEntity {
additionalPinInserter() {
return nodeVariadic(this)
}
/** @param {String} key */
showProperty(key) {
switch (key) {
case "Class":
case "Name":
case "Archetype":
case "ExportPath":
case "CustomProperties":
// Serielized separately, check doWrite()
return false
}
return super.showProperty(key)
}
toString(
insideString = false,
indentation = "",
printKey = this.Self().printKey,
) {
const moreIndentation = indentation + Configuration.indentation
let result = indentation + "Begin Object"
+ (this.Class?.type || this.Class?.path ? ` Class=${this.Class.toString(insideString)}` : "")
+ (this.Name ? ` Name=${this.Name.toString(insideString)}` : "")
+ (this.Archetype ? ` Archetype=${this.Archetype.toString(insideString)}` : "")
+ (this.ExportPath?.type || this.ExportPath?.path ? ` ExportPath=${this.ExportPath.toString(insideString)}` : "")
+ "\n"
+ super.toString(insideString, moreIndentation, k => this[k] instanceof ObjectEntity ? "" : k)
+ (!this.CustomProperties.Self().ignored
? this.getCustomproperties().map(pin =>
moreIndentation
+ printKey("CustomProperties ")
+ pin.toString(insideString)
+ this.Self().attributeSeparator
).join("")
: ""
)
+ indentation + "End Object"
return result
}
}

View File

@@ -11,11 +11,14 @@ export default class ObjectReferenceEntity extends IEntity {
+ `'(${Grammar.Regex.InsideSingleQuotedString.source})'`
)).map(([_0, a, b]) => a ?? b)
static typeReference = P.reg(
// @ts-expect-error
new RegExp(Grammar.Regex.Path.source + "|" + Grammar.symbol.getParser().regexp.source)
)
static fullReferenceGrammar = P.regArray(
new RegExp(
// @ts-expect-error
"(" + this.typeReference.getParser().regexp.source + ")"
// @ts-expect-error
+ "(?:" + this.#quotedParser.getParser().parser.regexp.source + ")"
)
).map(([full, type, ...path]) => new this(type, path.find(v => v), full))
@@ -30,7 +33,7 @@ export default class ObjectReferenceEntity extends IEntity {
this.fullReferenceSerializedGrammar,
this.fullReferenceGrammar,
this.typeReferenceGrammar,
)
).label("ObjectReferenceEntity")
#type
get type() {
@@ -72,7 +75,11 @@ export default class ObjectReferenceEntity extends IEntity {
return Utility.getNameFromPath(this.path.replace(/_C$/, ""), dropCounter)
}
toString() {
toString(
insideString = false,
indentation = "",
printKey = this.Self().printKey,
) {
return this.full
}
}

View File

@@ -1,20 +0,0 @@
import Grammar from "../serialization/Grammar.js"
import IEntity from "./IEntity.js"
export default class PathSymbolEntity extends IEntity {
static grammar = Grammar.symbol.map(v => new this(v))
constructor(value = "") {
super()
this.value = value
}
valueOf() {
return this.value
}
toString() {
return this.value.toString()
}
}

View File

@@ -32,7 +32,7 @@ import Vector2DEntity from "./Vector2DEntity.js"
import Vector4DEntity from "./Vector4DEntity.js"
import VectorEntity from "./VectorEntity.js"
/** @template {TerminalAttribute} T */
/** @template {IEntity} T */
export default class PinEntity extends IEntity {
static lookbehind = "INVTEXT"
@@ -120,25 +120,23 @@ export default class PinEntity extends IEntity {
constructor(values = {}) {
super(values)
/** @type {ObjectEntity} */ this.objectEntity
/** @type {Number} */ this.pinIndex
/** @type {GuidEntity} */ this.PinId
/** @type {String} */ this.PinName
/** @type {LocalizedTextEntity | String} */ this.PinFriendlyName
/** @type {String} */ this.PinToolTip
/** @type {String} */ this.Direction
/** @type {PinTypeEntity} */ this.PinType
/** @type {PinReferenceEntity[]} */ this.LinkedTo
/** @type {T} */ this.DefaultValue
/** @type {String} */ this.AutogeneratedDefaultValue
/** @type {ObjectReferenceEntity} */ this.DefaultObject
/** @type {GuidEntity} */ this.PersistentGuid
/** @type {Boolean} */ this.bHidden
/** @type {Boolean} */ this.bNotConnectable
/** @type {Boolean} */ this.bDefaultValueIsReadOnly
/** @type {Boolean} */ this.bDefaultValueIsIgnored
/** @type {Boolean} */ this.bAdvancedView
/** @type {Boolean} */ this.bOrphanedPin
/** @type {InstanceType<typeof PinEntity.attributes.PinId>} */ this.PinId
/** @type {InstanceType<typeof PinEntity.attributes.PinName>} */ this.PinName
/** @type {InstanceType<typeof PinEntity.attributes.PinFriendlyName>} */ this.PinFriendlyName
/** @type {InstanceType<typeof PinEntity.attributes.PinToolTip>} */ this.PinToolTip
/** @type {InstanceType<typeof PinEntity.attributes.Direction>} */ this.Direction
/** @type {InstanceType<typeof PinEntity.attributes.PinType>} */ this.PinType
/** @type {InstanceType<typeof PinEntity.attributes.LinkedTo>} */ this.LinkedTo
/** @type {InstanceType<typeof PinEntity.attributes.DefaultValue>} */ this.DefaultValue
/** @type {InstanceType<typeof PinEntity.attributes.AutogeneratedDefaultValue>} */ this.AutogeneratedDefaultValue
/** @type {InstanceType<typeof PinEntity.attributes.DefaultObject>} */ this.DefaultObject
/** @type {InstanceType<typeof PinEntity.attributes.PersistentGuid>} */ this.PersistentGuid
/** @type {InstanceType<typeof PinEntity.attributes.bHidden>} */ this.bHidden
/** @type {InstanceType<typeof PinEntity.attributes.bNotConnectable>} */ this.bNotConnectable
/** @type {InstanceType<typeof PinEntity.attributes.bDefaultValueIsReadOnly>} */ this.bDefaultValueIsReadOnly
/** @type {InstanceType<typeof PinEntity.attributes.bDefaultValueIsIgnored>} */ this.bDefaultValueIsIgnored
/** @type {InstanceType<typeof PinEntity.attributes.bAdvancedView>} */ this.bAdvancedView
/** @type {InstanceType<typeof PinEntity.attributes.bOrphanedPin>} */ this.bOrphanedPin
}
/** @param {ObjectEntity} objectEntity */
@@ -227,7 +225,6 @@ export default class PinEntity extends IEntity {
getDefaultValue(maybeCreate = false) {
if (this.DefaultValue === undefined && maybeCreate) {
// @ts-expect-error
this.DefaultValue = new (this.getEntityType(true))()
}
return this.DefaultValue
@@ -271,10 +268,7 @@ export default class PinEntity extends IEntity {
&& pinReferenceEntity.pinGuid.valueOf() == targetPinEntity.PinId.valueOf()
)
if (!linkFound) {
(this.LinkedTo ??= []).push(new PinReferenceEntity({
objectName: targetObjectName,
pinGuid: targetPinEntity.PinId,
}))
(this.LinkedTo ??= []).push(new PinReferenceEntity(targetObjectName, targetPinEntity.PinId,))
return true
}
return false // Already linked

View File

@@ -1,18 +1,20 @@
import P from "parsernostrum"
import GuidEntity from "./GuidEntity.js"
import IEntity from "./IEntity.js"
import PathSymbolEntity from "./PathSymbolEntity.js"
import SymbolEntity from "./SymbolEntity.js"
export default class PinReferenceEntity extends IEntity {
static grammar = P.seq(
PathSymbolEntity.grammar,
SymbolEntity.grammar,
P.whitespace,
GuidEntity.grammar
).map(([objectName, _1, pinGuid]) => new this(objectName, pinGuid))
)
.map(([objectName, _1, pinGuid]) => new this(objectName, pinGuid))
.label("PinReferenceEntity")
/**
* @param {PathSymbolEntity} objectName
* @param {SymbolEntity} objectName
* @param {GuidEntity} pinGuid
*/
constructor(objectName = null, pinGuid = null) {
@@ -20,4 +22,12 @@ export default class PinReferenceEntity extends IEntity {
this.objectName = objectName
this.pinGuid = pinGuid
}
toString(
insideString = false,
indentation = "",
printKey = this.Self().printKey,
) {
return this.objectName.toString() + " " + this.pinGuid.toString()
}
}

View File

@@ -3,8 +3,8 @@ import BooleanEntity from "./BooleanEntity.js"
import FunctionReferenceEntity from "./FunctionReferenceEntity.js"
import IEntity from "./IEntity.js"
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
import PathSymbolEntity from "./PathSymbolEntity.js"
import StringEntity from "./StringEntity.js"
import SymbolEntity from "./SymbolEntity.js"
export default class PinTypeEntity extends IEntity {
@@ -15,29 +15,29 @@ export default class PinTypeEntity extends IEntity {
PinSubCategoryObject: ObjectReferenceEntity.withDefault(),
PinSubCategoryMemberReference: FunctionReferenceEntity.withDefault(type => null),
PinValueType: PinTypeEntity.withDefault(),
ContainerType: PathSymbolEntity,
ContainerType: SymbolEntity,
bIsReference: BooleanEntity.withDefault(),
bIsConst: BooleanEntity.withDefault(),
bIsWeakPointer: BooleanEntity.withDefault(),
bIsUObjectWrapper: BooleanEntity.withDefault(),
bSerializeAsSinglePrecisionFloat: BooleanEntity.withDefault(),
}
static grammar = Grammar.createEntityGrammar(this)
static grammar = Grammar.createEntityGrammar(this).label("PinTypeEntity")
constructor(values = {}) {
super(values)
/** @type {String} */ this.PinCategory
/** @type {String} */ this.PinSubCategory
/** @type {ObjectReferenceEntity} */ this.PinSubCategoryObject
/** @type {FunctionReferenceEntity} */ this.PinSubCategoryMemberReference
/** @type {PinTypeEntity} */ this.PinValueType
/** @type {PathSymbolEntity} */ this.ContainerType
/** @type {Boolean} */ this.bIsReference
/** @type {Boolean} */ this.bIsConst
/** @type {Boolean} */ this.bIsWeakPointer
/** @type {Boolean} */ this.bIsUObjectWrapper
/** @type {Boolean} */ this.bIsUObjectWrapper
/** @type {Boolean} */ this.bSerializeAsSinglePrecisionFloat
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinCategory>} */ this.PinCategory
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinSubCategory>} */ this.PinSubCategory
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinSubCategoryObject>} */ this.PinSubCategoryObject
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinSubCategoryMemberReference>} */ this.PinSubCategoryMemberReference
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinValueType>} */ this.PinValueType
/** @type {InstanceType<typeof PinTypeEntity.attributes.ContainerType>} */ this.ContainerType
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsReference>} */ this.bIsReference
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsConst>} */ this.bIsConst
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsWeakPointer>} */ this.bIsWeakPointer
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsUObjectWrapper>} */ this.bIsUObjectWrapper
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsUObjectWrapper>} */ this.bIsUObjectWrapper
/** @type {InstanceType<typeof PinTypeEntity.attributes.bSerializeAsSinglePrecisionFloat>} */ this.bSerializeAsSinglePrecisionFloat
}
/** @param {PinTypeEntity} other */

View File

@@ -1,17 +1,18 @@
import P from "parsernostrum"
import Grammar from "../serialization/Grammar.js"
import Vector2DEntity from "./Vector2DEntity.js"
export default class RBSerializationVector2DEntity extends Vector2DEntity {
static grammar = P.alt(
P.regArray(new RegExp(
/X\s*=\s*/.source + "(?<x>" + P.number.getParser().parser.regexp.source + ")"
/X\s*=\s*/.source + "(?<x>" + Grammar.numberRegexSource + ")"
+ "\\s+"
+ /Y\s*=\s*/.source + "(?<y>" + P.number.getParser().parser.regexp.source + ")"
+ /Y\s*=\s*/.source + "(?<y>" + Grammar.numberRegexSource + ")"
)).map(({ groups: { x, y } }) => new this({
X: Number(x),
Y: Number(y),
})),
Vector2DEntity.grammar
)
).label("RBSerializationVector2DEntity")
}

View File

@@ -10,13 +10,13 @@ export default class RotatorEntity extends IEntity {
P: NumberEntity.withDefault(),
Y: NumberEntity.withDefault(),
}
static grammar = Grammar.createEntityGrammar(this, false)
static grammar = Grammar.createEntityGrammar(this).label("RotatorEntity")
constructor(values) {
super(values)
/** @type {NumberEntity} */ this.R
/** @type {NumberEntity} */ this.P
/** @type {NumberEntity} */ this.Y
/** @type {InstanceType<typeof RotatorEntity.attributes.R>} */ this.R
/** @type {InstanceType<typeof RotatorEntity.attributes.P>} */ this.P
/** @type {InstanceType<typeof RotatorEntity.attributes.Y>} */ this.Y
}
getRoll() {

View File

@@ -10,11 +10,11 @@ export default class ScriptVariableEntity extends IEntity {
ScriptVariable: ObjectReferenceEntity,
OriginalChangeId: GuidEntity,
}
static grammar = Grammar.createEntityGrammar(this)
static grammar = Grammar.createEntityGrammar(this).label("ScriptVariableEntity")
constructor(values = {}) {
super(values)
/** @type {ObjectReferenceEntity} */ this.ScriptVariable
/** @type {GuidEntity} */ this.OriginalChangeId
/** @type {InstanceType<typeof ScriptVariableEntity.attributes.ScriptVariable>} */ this.ScriptVariable
/** @type {InstanceType<typeof ScriptVariableEntity.attributes.OriginalChangeId>} */ this.OriginalChangeId
}
}

View File

@@ -1,15 +1,16 @@
import P from "parsernostrum"
import Grammar from "../serialization/Grammar.js"
import RotatorEntity from "./RotatorEntity.js"
export default class SimpleSerializationRotatorEntity extends RotatorEntity {
static grammar = P.alt(
P.regArray(new RegExp(
`(${P.number.getParser().parser.regexp.source})`
`(${Grammar.numberRegexSource})`
+ String.raw`\s*,\s*`
+ `(${P.number.getParser().parser.regexp.source})`
+ `(${Grammar.numberRegexSource})`
+ String.raw`\s*,\s*`
+ `(${P.number.getParser().parser.regexp.source})`
+ `(${Grammar.numberRegexSource})`
)).map(([_, p, y, r]) => new this({
R: Number(r),
P: Number(p),

View File

@@ -1,13 +1,14 @@
import P from "parsernostrum"
import Grammar from "../serialization/Grammar.js"
import Vector2DEntity from "./Vector2DEntity.js"
export default class SimpleSerializationVector2DEntity extends Vector2DEntity {
static grammar = P.alt(
P.regArray(new RegExp(
`(${P.number.getParser().parser.regexp.source})`
`(${Grammar.numberRegexSource})`
+ String.raw`\s*,\s*`
+ `(${P.number.getParser().parser.regexp.source})`
+ `(${Grammar.numberRegexSource})`
)).map(([_, x, y]) => new this({
X: Number(x),
Y: Number(y),

View File

@@ -1,4 +1,5 @@
import P from "parsernostrum"
import Grammar from "../serialization/Grammar.js"
import Vector4DEntity from "./Vector4DEntity.js"
export default class SimpleSerializationVector4DEntity extends Vector4DEntity {
@@ -6,16 +7,16 @@ export default class SimpleSerializationVector4DEntity extends Vector4DEntity {
static grammar = this.createGrammar()
static createGrammar() {
const number = P.number.getParser().parser.regexp.source
const number = Grammar.numberRegexSource
return P.alt(
P.regArray(new RegExp(
`(${P.number.getParser().parser.regexp.source})`
`(${Grammar.numberRegexSource})`
+ String.raw`\s*,\s*`
+ `(${P.number.getParser().parser.regexp.source})`
+ `(${Grammar.numberRegexSource})`
+ String.raw`\s*,\s*`
+ `(${P.number.getParser().parser.regexp.source})`
+ `(${Grammar.numberRegexSource})`
+ String.raw`\s*,\s*`
+ `(${P.number.getParser().parser.regexp.source})`
+ `(${Grammar.numberRegexSource})`
))
.map(([_0, x, y, z, w]) => new this({
X: Number(x),

View File

@@ -1,15 +1,16 @@
import P from "parsernostrum"
import Grammar from "../serialization/Grammar.js"
import VectorEntity from "./VectorEntity.js"
export default class SimpleSerializationVectorEntity extends VectorEntity {
static grammar = P.alt(
P.regArray(new RegExp(
`(${P.number.getParser().parser.regexp.source})`
`(${Grammar.numberRegexSource})`
+ String.raw`\s*,\s*`
+ `(${P.number.getParser().parser.regexp.source})`
+ `(${Grammar.numberRegexSource})`
+ String.raw`\s*,\s*`
+ `(${P.number.getParser().parser.regexp.source})`
+ `(${Grammar.numberRegexSource})`
))
.map(([_0, x, y, z]) => new this({
X: Number(x),

View File

@@ -1,10 +1,12 @@
import P from "parsernostrum"
import IEntity from "./IEntity.js"
import Utility from "../Utility.js"
import IPrintableEntity from "./IPrintableEntity.js"
export default class StringEntity extends IEntity {
export default class StringEntity extends IPrintableEntity {
static grammar = P.doubleQuotedString.map(insideString => Utility.unescapeString(insideString))
static grammar = P.doubleQuotedString
.map(insideString => new this(Utility.unescapeString(insideString)))
.label("StringEntity")
/** @param {String} value */
constructor(value = "") {
@@ -12,11 +14,19 @@ export default class StringEntity extends IEntity {
this.value = value
}
print() {
return this.value
}
valueOf() {
return this.value
}
toString() {
return this.value.toString()
toString(insideString = false) {
let result = Utility.escapeString(this.value)
if (!insideString) {
result = `"${result}"`
}
return result
}
}

View File

@@ -3,7 +3,7 @@ import IEntity from "./IEntity.js"
export default class SymbolEntity extends IEntity {
static grammar = Grammar.symbol.map(v => new this(v))
static grammar = Grammar.symbol.map(v => new this(v)).label("SymbolEntity")
/** @param {String} value */
constructor(value = "") {

View File

@@ -4,7 +4,6 @@ import IEntity from "./IEntity.js"
export default class UnknownKeysEntity extends IEntity {
static grammar = P.seq(
// Lookbehind
P.reg(new RegExp(`(${Grammar.Regex.Path.source}|${Grammar.Regex.Symbol.source}\\s*)?\\(\\s*`), 1),
@@ -24,7 +23,7 @@ export default class UnknownKeysEntity extends IEntity {
}
attributes.forEach(attributeSetter => attributeSetter(values))
return new this(values)
})
}).label("UnknownKeysEntity")
constructor(values = {}) {
super(values)

View File

@@ -16,5 +16,5 @@ export default class UnknownPinEntity extends PinEntity {
}
attributes.forEach(attributeSetter => attributeSetter(values))
return new this(values)
})
}).label("UnknownPinEntity")
}

View File

@@ -13,12 +13,13 @@ export default class VariableReferenceEntity extends IEntity {
MemberGuid: GuidEntity,
bSelfContext: BooleanEntity,
}
static grammar = Grammar.createEntityGrammar(this)
static grammar = Grammar.createEntityGrammar(this).label("VariableReferenceEntity")
constructor(values) {
super(values)
/** @type {String} */ this.MemberName
/** @type {GuidEntity} */ this.GuidEntity
/** @type {Boolean} */ this.bSelfContext
/** @type {InstanceType<typeof VariableReferenceEntity.attributes.MemberScope>} */ this.MemberScope
/** @type {InstanceType<typeof VariableReferenceEntity.attributes.MemberName>} */ this.MemberName
/** @type {InstanceType<typeof VariableReferenceEntity.attributes.MemberGuid>} */ this.MemberGuid
/** @type {InstanceType<typeof VariableReferenceEntity.attributes.bSelfContext>} */ this.bSelfContext
}
}

View File

@@ -9,12 +9,12 @@ export default class Vector2DEntity extends IEntity {
X: NumberEntity.withDefault(),
Y: NumberEntity.withDefault(),
}
static grammar = Grammar.createEntityGrammar(this, false)
static grammar = Grammar.createEntityGrammar(this).label("Vector2DEntity")
constructor(values) {
super(values)
/** @type {NumberEntity} */ this.X
/** @type {NumberEntity} */ this.Y
/** @type {InstanceType<typeof Vector2DEntity.attributes.X>} */ this.X
/** @type {InstanceType<typeof Vector2DEntity.attributes.Y>} */ this.Y
}
/** @returns {[Number, Number]} */

View File

@@ -11,14 +11,14 @@ export default class Vector4DEntity extends IEntity {
Z: NumberEntity.withDefault(),
W: NumberEntity.withDefault(),
}
static grammar = Grammar.createEntityGrammar(Vector4DEntity, false)
static grammar = Grammar.createEntityGrammar(this).label("Vector4DEntity")
constructor(values) {
super(values)
/** @type {NumberEntity} */ this.X
/** @type {NumberEntity} */ this.Y
/** @type {NumberEntity} */ this.Z
/** @type {NumberEntity} */ this.W
/** @type {InstanceType<typeof Vector4DEntity.attributes.X>} */ this.X
/** @type {InstanceType<typeof Vector4DEntity.attributes.Y>} */ this.Y
/** @type {InstanceType<typeof Vector4DEntity.attributes.Z>} */ this.Z
/** @type {InstanceType<typeof Vector4DEntity.attributes.W>} */ this.W
}
/** @returns {[Number, Number, Number, Number]} */

View File

@@ -10,13 +10,13 @@ export default class VectorEntity extends IEntity {
Y: NumberEntity.withDefault(),
Z: NumberEntity.withDefault(),
}
static grammar = Grammar.createEntityGrammar(VectorEntity, false)
static grammar = Grammar.createEntityGrammar(this).label("VectorEntity")
constructor(values) {
super(values)
/** @type {NumberEntity} */ this.X
/** @type {NumberEntity} */ this.Y
/** @type {NumberEntity} */ this.Z
/** @type {InstanceType<typeof VectorEntity.attributes.X>} */ this.X
/** @type {InstanceType<typeof VectorEntity.attributes.Y>} */ this.Y
/** @type {InstanceType<typeof VectorEntity.attributes.X>} */ this.Z
}
/** @returns {[Number, Number, Number]} */