mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-03-17 05:47:34 +08:00
Still WIP
This commit is contained in:
29
js/entity/AlternativesEntity.js
Normal file
29
js/entity/AlternativesEntity.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class AlternativesEntity extends IEntity {
|
||||
|
||||
/** @type {(typeof IEntity)[]} */
|
||||
static alternatives = []
|
||||
|
||||
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)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {(typeof IEntity)[]} Types
|
||||
* @param {Types} types
|
||||
*/
|
||||
static accepting(...types) {
|
||||
const result = /** @type {typeof AlternativesEntity & { alternatives: Types }} */(this.asUniqueClass())
|
||||
result.alternatives = types
|
||||
result.grammar = result.createGrammar()
|
||||
return result
|
||||
}
|
||||
}
|
||||
41
js/entity/ArrayEntity.js
Normal file
41
js/entity/ArrayEntity.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
/** @template {typeof IEntity} T */
|
||||
export default class ArrayEntity extends IEntity {
|
||||
|
||||
/** @type {typeof IEntity} */
|
||||
static type
|
||||
|
||||
/** @param {InstanceType<T>[]} values */
|
||||
constructor(values = []) {
|
||||
super()
|
||||
this.values = values
|
||||
}
|
||||
|
||||
static createGrammar(elementGrammar = this.type.grammar) {
|
||||
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 : []))
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @param {NonNullable<T>} type
|
||||
*/
|
||||
static of(type) {
|
||||
const result = /** @type {(typeof ArrayEntity<T>) & { type: T }} */(this.asUniqueClass())
|
||||
result.type = type
|
||||
this.grammar = result.createGrammar()
|
||||
return result
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.values
|
||||
}
|
||||
}
|
||||
20
js/entity/BooleanEntity.js
Executable file
20
js/entity/BooleanEntity.js
Executable file
@@ -0,0 +1,20 @@
|
||||
import P from "parsernostrum"
|
||||
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))
|
||||
|
||||
constructor(value = false) {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value.toString()
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,13 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import P from "parsernostrum"
|
||||
import IntegerEntity from "./IntegerEntity.js"
|
||||
|
||||
export default class ByteEntity extends IntegerEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: new AttributeInfo({
|
||||
...super.attributes.value,
|
||||
predicate: v => v % 1 == 0 && v >= 0 && v < 1 << 8,
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = P.numberByte.map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.numberByte.map(v => new this(v))
|
||||
}
|
||||
|
||||
constructor(values = 0) {
|
||||
super(values)
|
||||
set value(value) {
|
||||
if (value % 1 == 0 && value >= 0 && value < 1 << 8) {
|
||||
super.value = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,13 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import P from "parsernostrum"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class ColorChannelEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: AttributeInfo.createValue(0),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = P.number.map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.number.map(value => new this(value))
|
||||
}
|
||||
|
||||
constructor(values = 0) {
|
||||
if (values.constructor !== Object) {
|
||||
// @ts-expect-error
|
||||
values = {
|
||||
value: values,
|
||||
}
|
||||
}
|
||||
super(values)
|
||||
/** @type {Number} */ this.value
|
||||
constructor(value = 0) {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
export default class ComputedType {
|
||||
|
||||
#f
|
||||
|
||||
/** @param {Function} f */
|
||||
constructor(f) {
|
||||
this.#f = f
|
||||
}
|
||||
|
||||
/** @param {IEntity} entity */
|
||||
compute(entity) {
|
||||
return this.#f(entity)
|
||||
}
|
||||
}
|
||||
22
js/entity/ComputedTypeEntity.js
Normal file
22
js/entity/ComputedTypeEntity.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class ComputedTypeEntity extends IEntity {
|
||||
|
||||
/** @type {(entity: IEntity) => typeof IEntity} */
|
||||
static f
|
||||
|
||||
/**
|
||||
* @template {typeof ComputedTypeEntity.f} T
|
||||
* @param {T} producer
|
||||
*/
|
||||
static from(producer) {
|
||||
const result = /** @type {(typeof ComputedTypeEntity) & { f: T }} */(this.asUniqueClass())
|
||||
result.f = producer
|
||||
return result
|
||||
}
|
||||
|
||||
/** @param {IEntity} entity */
|
||||
compute(entity) {
|
||||
return /** @type {typeof ComputedTypeEntity} */(this.Self()).f(entity)
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import EnumEntity from "./EnumEntity.js"
|
||||
|
||||
export default class EnumDisplayValueEntity extends EnumEntity {
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.reg(Grammar.Regex.InsideString).map(v => new this(v))
|
||||
}
|
||||
static grammar = P.reg(Grammar.Regex.InsideString).map(v => new this(v))
|
||||
}
|
||||
|
||||
@@ -3,9 +3,5 @@ import SymbolEntity from "./SymbolEntity.js"
|
||||
|
||||
export default class EnumEntity extends SymbolEntity {
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.symbol.map(v => new this(v))
|
||||
}
|
||||
static grammar = Grammar.symbol.map(v => new this(v))
|
||||
}
|
||||
|
||||
@@ -1,55 +1,38 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import P from "parsernostrum"
|
||||
import IEntity from "./IEntity.js"
|
||||
import InvariantTextEntity from "./InvariantTextEntity.js"
|
||||
import LocalizedTextEntity from "./LocalizedTextEntity.js"
|
||||
import Union from "./Union.js"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
|
||||
export default class FormatTextEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: new AttributeInfo({
|
||||
type: [new Union(String, LocalizedTextEntity, InvariantTextEntity, FormatTextEntity)],
|
||||
default: [],
|
||||
}),
|
||||
lookbehind: /** @type {AttributeInfo<Union<String[]>>} */(new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: new Union("LOCGEN_FORMAT_NAMED", "LOCGEN_FORMAT_ORDERED"),
|
||||
})),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(
|
||||
// Resulting regex: /(LOCGEN_FORMAT_NAMED|LOCGEN_FORMAT_ORDERED)\s*/
|
||||
new RegExp(`(${this.attributes.lookbehind.default.values.reduce((acc, cur) => acc + "|" + cur)})\\s*`),
|
||||
1
|
||||
),
|
||||
Grammar.grammarFor(this.attributes.value)
|
||||
)
|
||||
.map(([lookbehind, values]) => {
|
||||
const result = new this({
|
||||
value: values,
|
||||
lookbehind,
|
||||
})
|
||||
return result
|
||||
})
|
||||
}
|
||||
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.alt(
|
||||
...[StringEntity, LocalizedTextEntity, InvariantTextEntity, FormatTextEntity].map(type => type.grammar)
|
||||
).sepBy(P.reg(/\s*\,\s*/)),
|
||||
P.reg(/\s*\)/)
|
||||
)
|
||||
.map(([lookbehind, values]) => {
|
||||
const result = new this(values)
|
||||
result.lookbehind = lookbehind
|
||||
return result
|
||||
})
|
||||
|
||||
/** @param {(StringEntity | LocalizedTextEntity | InvariantTextEntity | FormatTextEntity)[]} values */
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {(String | LocalizedTextEntity | InvariantTextEntity | FormatTextEntity)[]} */ this.value
|
||||
super()
|
||||
this.values = values
|
||||
}
|
||||
|
||||
toString() {
|
||||
const pattern = this.value?.[0]?.toString() // The pattern is always the first element of the array
|
||||
const pattern = this.values?.[0]?.toString() // The pattern is always the first element of the array
|
||||
if (!pattern) {
|
||||
return ""
|
||||
}
|
||||
const values = this.value.slice(1).map(v => v.toString())
|
||||
const values = this.values.slice(1).map(v => v.toString())
|
||||
return this.lookbehind == "LOCGEN_FORMAT_NAMED"
|
||||
? pattern.replaceAll(/\{([a-zA-Z]\w*)\}/g, (substring, arg) => {
|
||||
const argLocation = values.indexOf(arg) + 1
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
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"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
|
||||
export default class FunctionReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
MemberParent: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MemberName: AttributeInfo.createType(String),
|
||||
MemberGuid: AttributeInfo.createType(GuidEntity),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this)
|
||||
MemberParent: ObjectReferenceEntity,
|
||||
MemberName: StringEntity,
|
||||
MemberGuid: GuidEntity,
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import P from "parsernostrum"
|
||||
|
||||
var crypto
|
||||
if (typeof window === "undefined") {
|
||||
@@ -11,39 +10,21 @@ if (typeof window === "undefined") {
|
||||
|
||||
export default class GuidEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: AttributeInfo.createValue(""),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = P.reg(/[0-9a-fA-F]{32}/).map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.guid.map(v => new this(v))
|
||||
}
|
||||
|
||||
static generateGuid(random = true) {
|
||||
static generateGuid() {
|
||||
let values = new Uint32Array(4)
|
||||
if (random === true) {
|
||||
crypto.getRandomValues(values)
|
||||
}
|
||||
crypto.getRandomValues(values)
|
||||
let guid = ""
|
||||
values.forEach(n => {
|
||||
guid += ("0".repeat(8) + n.toString(16).toUpperCase()).slice(-8)
|
||||
})
|
||||
return new GuidEntity({ value: guid })
|
||||
return guid
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
if (!values) {
|
||||
values = GuidEntity.generateGuid().value
|
||||
}
|
||||
if (values.constructor !== Object) {
|
||||
values = {
|
||||
value: values,
|
||||
}
|
||||
}
|
||||
super(values)
|
||||
/** @type {String} */ this.value
|
||||
constructor(value = GuidEntity.generateGuid()) {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
|
||||
@@ -1,169 +1,165 @@
|
||||
import Configuration from "../Configuration.js"
|
||||
import P from "parsernostrum"
|
||||
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"
|
||||
|
||||
/** @abstract */
|
||||
export default class IEntity extends Serializable {
|
||||
export default class IEntity {
|
||||
|
||||
/** @type {{ [attribute: String]: AttributeInfo }} */
|
||||
static attributes = {
|
||||
attributes: new AttributeInfo({
|
||||
ignored: true,
|
||||
}),
|
||||
lookbehind: new AttributeInfo({
|
||||
default: /** @type {String | Union<String[]>} */(""),
|
||||
ignored: true,
|
||||
uninitialized: true,
|
||||
}),
|
||||
/** @type {(v: String) => String} */
|
||||
static same = v => v
|
||||
|
||||
/** @type {(entity: Attribute, serialized: String) => String} */
|
||||
static notWrapped = (entity, serialized) => serialized
|
||||
|
||||
/** @type {(entity: Attribute, serialized: String) => String} */
|
||||
static bracketsWrapped = (entity, serialized) => `(${serialized})`
|
||||
|
||||
static wrap = this.notWrapped
|
||||
|
||||
static attributeSeparator = ","
|
||||
|
||||
static trailingSeparator = false
|
||||
|
||||
/** @type {(k: String) => String} */
|
||||
static printKey = k => k
|
||||
|
||||
/** @type {P<Parser>} */
|
||||
static grammar = 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
|
||||
#keys
|
||||
get keys() {
|
||||
return this.#keys ?? Object.keys(this.Self().attributes)
|
||||
}
|
||||
set _keys(keys) {
|
||||
this.#_keys = keys
|
||||
set keys(value) {
|
||||
this.#keys = [... new Set(value)]
|
||||
}
|
||||
|
||||
constructor(values = {}, suppressWarns = false) {
|
||||
super()
|
||||
const Self = /** @type {typeof IEntity} */(this.constructor)
|
||||
/** @type {AttributeDeclarations?} */ this.attributes
|
||||
/** @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 ${key} (of type ${typeName}) in the serialized data is not defined in ${Self.name}.attributes`
|
||||
)
|
||||
}
|
||||
}
|
||||
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[key] = value
|
||||
/** @type {(type: typeof IEntity) => InstanceType<typeof IEntity>} */
|
||||
static default
|
||||
static nullable = false
|
||||
static ignored = false // Never serialize or deserialize
|
||||
static serialized = false // Value is written and read as string
|
||||
static expected = false // Must be there
|
||||
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
|
||||
|
||||
constructor(values = {}) {
|
||||
const keys = Utility.mergeArrays(Object.keys(values.attributes), Object.keys(this.Self().attributes))
|
||||
for (const key of keys) {
|
||||
if (values[key] !== undefined) {
|
||||
this[key] = values[key]
|
||||
continue
|
||||
}
|
||||
Self.attributes.lookbehind
|
||||
const predicate = AttributeInfo.getAttribute(values, key, "predicate", Self)
|
||||
const assignAttribute = !predicate
|
||||
? v => this[key] = v
|
||||
: v => {
|
||||
Object.defineProperties(this, {
|
||||
["#" + key]: {
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
},
|
||||
[key]: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this["#" + key]
|
||||
},
|
||||
set(v) {
|
||||
if (!predicate(v)) {
|
||||
console.warn(
|
||||
`UEBlueprint: Tried to assign attribute ${key} to ${Self.name} not satisfying the predicate`
|
||||
)
|
||||
return
|
||||
}
|
||||
this["#" + key] = v
|
||||
}
|
||||
},
|
||||
})
|
||||
this[key] = v
|
||||
}
|
||||
|
||||
let defaultValue = AttributeInfo.getAttribute(values, key, "default", Self)
|
||||
if (defaultValue instanceof Function) {
|
||||
defaultValue = defaultValue(this)
|
||||
}
|
||||
let defaultType = AttributeInfo.getAttribute(values, key, "type", Self)
|
||||
if (defaultType instanceof ComputedType) {
|
||||
defaultType = defaultType.compute(this)
|
||||
}
|
||||
if (defaultType instanceof Array) {
|
||||
defaultType = Array
|
||||
}
|
||||
if (defaultType === undefined) {
|
||||
defaultType = Utility.getType(defaultValue)
|
||||
}
|
||||
|
||||
if (value !== undefined) {
|
||||
// Remember value can still be null
|
||||
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 (defaultValue !== undefined && !AttributeInfo.getAttribute(values, key, "uninitialized", Self)) {
|
||||
assignAttribute(defaultValue)
|
||||
const attribute = this.Self().attributes[key]
|
||||
if (attribute.default !== undefined) {
|
||||
this[key] = attribute.default(attribute)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {AttributeTypeDescription} attributeType */
|
||||
static defaultValueProviderFromType(attributeType) {
|
||||
if (attributeType === Boolean) {
|
||||
return false
|
||||
} else if (attributeType === Number) {
|
||||
return 0
|
||||
} else if (attributeType === BigInt) {
|
||||
return 0n
|
||||
} else if (attributeType === String) {
|
||||
return ""
|
||||
} else if (attributeType === Array || attributeType instanceof Array) {
|
||||
return () => []
|
||||
} else if (attributeType instanceof Union) {
|
||||
return this.defaultValueProviderFromType(attributeType.values[0])
|
||||
} else if (attributeType instanceof MirroredEntity) {
|
||||
return () => new MirroredEntity(attributeType.type, attributeType.getter)
|
||||
} else if (attributeType instanceof ComputedType) {
|
||||
return undefined
|
||||
} else {
|
||||
return () => new /** @type {AnyConstructor<Attribute>} */(attributeType)()
|
||||
/** @param {String} key */
|
||||
showProperty(key) {
|
||||
/** @type {IEntity} */
|
||||
let value = this[key]
|
||||
const Self = value.Self()
|
||||
if (Self.silent && Self.default !== undefined) {
|
||||
if (Self["#default"] === undefined) {
|
||||
Self["#default"] = Self.default(Self)
|
||||
}
|
||||
const defaultValue = Self["#default"]
|
||||
return !value.equals(defaultValue)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {new (...args: any) => any} C
|
||||
* @param {C} type
|
||||
* @returns {value is InstanceType<C>}
|
||||
* @protected
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
* @returns {T}
|
||||
*/
|
||||
static isValueOfType(value, type) {
|
||||
return value != null && (value instanceof type || value.constructor === type)
|
||||
static asUniqueClass() {
|
||||
if (this.name.length) {
|
||||
// @ts-expect-error
|
||||
return class extends this { }
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
static defineAttributes(object, attributes) {
|
||||
Object.defineProperty(object, "attributes", {
|
||||
writable: true,
|
||||
configurable: false,
|
||||
})
|
||||
object.attributes = attributes
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
*/
|
||||
static withDefault(value = /** @type {(type: T) => InstanceType<T>} */(type => new type())) {
|
||||
const result = this.asUniqueClass()
|
||||
result.default = value
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
*/
|
||||
static flagNullable(value = true) {
|
||||
const result = this.asUniqueClass()
|
||||
result.nullable = value
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
*/
|
||||
static flagSerialized(value = true) {
|
||||
const result = this.asUniqueClass()
|
||||
result.serialized = value
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
*/
|
||||
static flagInlined(value = true) {
|
||||
const result = this.asUniqueClass()
|
||||
result.inlined = value
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
*/
|
||||
static flagSilent(value = true) {
|
||||
const result = this.asUniqueClass()
|
||||
result.silent = value
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {InstanceType<T>}
|
||||
*/
|
||||
Self() {
|
||||
return /** @type {T} */(this.constructor)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,27 +189,16 @@ export default class IEntity extends Serializable {
|
||||
return this["#" + attribute]
|
||||
},
|
||||
set(v) {
|
||||
if (v == this["#" + attribute]) {
|
||||
return
|
||||
if (v != this["#" + attribute]) {
|
||||
callback(v)
|
||||
this["#" + attribute] = v
|
||||
}
|
||||
callback(v)
|
||||
this["#" + attribute] = v
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getLookbehind() {
|
||||
let lookbehind = this.lookbehind ?? AttributeInfo.getAttribute(this, "lookbehind", "default")
|
||||
lookbehind = lookbehind instanceof Union ? lookbehind.values[0] : lookbehind
|
||||
return lookbehind
|
||||
}
|
||||
|
||||
unexpectedKeys() {
|
||||
return Object.keys(this).length - Object.keys(/** @type {typeof IEntity} */(this.constructor).attributes).length
|
||||
}
|
||||
|
||||
/** @param {IEntity} other */
|
||||
equals(other) {
|
||||
const thisKeys = Object.keys(this)
|
||||
@@ -221,13 +206,53 @@ export default class IEntity extends Serializable {
|
||||
if (thisKeys.length != otherKeys.length) {
|
||||
return false
|
||||
}
|
||||
for (const key of thisKeys) {
|
||||
if (this[key] instanceof IEntity && !this[key].equals(other[key])) {
|
||||
return false
|
||||
} else if (!Utility.equals(this[key], other[key])) {
|
||||
for (let i = 0; i < thisKeys.length; ++i) {
|
||||
if (!(this[thisKeys[i]] instanceof IEntity && this[thisKeys[i]].equals(other[otherKeys[i]]))) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
toString(
|
||||
insideString = false,
|
||||
indentation = "",
|
||||
printKey = this.Self().printKey,
|
||||
) {
|
||||
const Self = this.Self()
|
||||
let result = ""
|
||||
let first = true
|
||||
for (const key of this.keys) {
|
||||
/** @type {IEntity} */
|
||||
const value = this[key]
|
||||
if (value === undefined || !this.showProperty(key)) {
|
||||
continue
|
||||
}
|
||||
if (first) {
|
||||
first = false
|
||||
} else {
|
||||
result += Self.attributeSeparator
|
||||
}
|
||||
if (Self.inlined) {
|
||||
result += value.toString(insideString, indentation, k => printKey(`${key}.${k}`))
|
||||
continue
|
||||
}
|
||||
let keyValue = printKey(key)
|
||||
if (keyValue.length) {
|
||||
if (Self.quoted) {
|
||||
keyValue = `"${keyValue}"`
|
||||
}
|
||||
result += Self.attributeSeparator.includes("\n") ? indentation : ""
|
||||
}
|
||||
let serialization = value.toString(insideString, indentation, printKey)
|
||||
if (Self.serialized) {
|
||||
serialization = `"${serialization.replaceAll(/(?<=(?:[^\\]|^)(?:\\\\)*?)"/, '\\"')}"`
|
||||
}
|
||||
result += serialization
|
||||
}
|
||||
if (Self.trailingSeparator && result.length) {
|
||||
result += Self.attributeSeparator
|
||||
}
|
||||
return Self.wrap(this, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,18 @@
|
||||
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: AttributeInfo.createValue(""),
|
||||
}
|
||||
static attributeConverter = {
|
||||
fromAttribute: (value, type) => new IdentifierEntity(value),
|
||||
toAttribute: (value, type) => value.toString()
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = Grammar.symbol.map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.symbol.map(v => new this(v))
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
if (values.constructor !== Object) {
|
||||
values = {
|
||||
value: values,
|
||||
}
|
||||
}
|
||||
super(values)
|
||||
/** @type {String} */ this.value
|
||||
/** @param {String} value */
|
||||
constructor(value) {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
@@ -33,6 +20,6 @@ export default class IdentifierEntity extends IEntity {
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value
|
||||
return this.value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,25 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import P from "parsernostrum"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class Integer64Entity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: new AttributeInfo({
|
||||
default: 0n,
|
||||
predicate: v => v >= -(1n << 63n) && v < 1n << 63n,
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = P.numberBigInteger.map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.numberBigInteger.map(v => new this(v))
|
||||
/** @type {bigint} */
|
||||
#value
|
||||
get value() {
|
||||
return this.#value
|
||||
}
|
||||
set value(value) {
|
||||
if (value >= -(1n << 63n) && value < 1n << 63n) {
|
||||
this.#value = value
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {BigInt | Number | Object} values */
|
||||
constructor(values = 0) {
|
||||
if (values.constructor !== Object) {
|
||||
values = {
|
||||
value: values,
|
||||
}
|
||||
}
|
||||
if (values.value === -0) {
|
||||
values.value = 0n
|
||||
}
|
||||
super(values)
|
||||
/** @type {BigInt} */ this.value
|
||||
/** @param {bigint | Number} value */
|
||||
constructor(value = 0n) {
|
||||
super()
|
||||
this.value = BigInt(value)
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
|
||||
@@ -1,42 +1,15 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import P from "parsernostrum"
|
||||
import NumberEntity from "./NumberEntity.js"
|
||||
|
||||
export default class IntegerEntity extends IEntity {
|
||||
// @ts-expect-error
|
||||
export default class IntegerEntity extends NumberEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: new AttributeInfo({
|
||||
default: 0,
|
||||
predicate: v => v % 1 == 0 && v > 1 << 31 && v < -(1 << 31),
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = P.numberInteger.map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.numberInteger.map(v => new this(v))
|
||||
}
|
||||
|
||||
/** @param {Number | Object} values */
|
||||
constructor(values = 0) {
|
||||
if (values.constructor !== Object) {
|
||||
values = {
|
||||
value: values,
|
||||
}
|
||||
set value(value) {
|
||||
if (value >= -(1 << 31) && value < 1 << 31) {
|
||||
value = Math.floor(value)
|
||||
super.value = value
|
||||
}
|
||||
values.value = Math.floor(values.value)
|
||||
if (values.value === -0) {
|
||||
values.value = 0
|
||||
}
|
||||
super(values)
|
||||
/** @type {Number} */ this.value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,22 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import P from "parsernostrum"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class InvariantTextEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
value: AttributeInfo.createValue(""),
|
||||
lookbehind: new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: "INVTEXT",
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static lookbehind = "INVTEXT"
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.alt(
|
||||
Parsernostrum.seq(
|
||||
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.attributes.lookbehind.default)) // InvariantTextEntity can not have arguments
|
||||
.map(() => "")
|
||||
).map(value => new this(value))
|
||||
}
|
||||
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))
|
||||
|
||||
constructor(values) {
|
||||
if (values.constructor !== Object) {
|
||||
values = {
|
||||
value: values,
|
||||
}
|
||||
}
|
||||
super(values)
|
||||
/** @type {String} */ this.value
|
||||
constructor(value = "") {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -1,33 +1,32 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import BooleanEntity from "./BooleanEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import IdentifierEntity from "./IdentifierEntity.js"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
|
||||
export default class KeyBindingEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
ActionName: AttributeInfo.createValue(""),
|
||||
bShift: AttributeInfo.createValue(false),
|
||||
bCtrl: AttributeInfo.createValue(false),
|
||||
bAlt: AttributeInfo.createValue(false),
|
||||
bCmd: AttributeInfo.createValue(false),
|
||||
Key: AttributeInfo.createType(IdentifierEntity),
|
||||
ActionName: StringEntity,
|
||||
bShift: BooleanEntity,
|
||||
bCtrl: BooleanEntity,
|
||||
bAlt: BooleanEntity,
|
||||
bCmd: BooleanEntity,
|
||||
Key: IdentifierEntity,
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = P.alt(
|
||||
IdentifierEntity.grammar.map(identifier => {
|
||||
const result = new this()
|
||||
result.Key = identifier
|
||||
return result
|
||||
}),
|
||||
Grammar.createEntityGrammar(this)
|
||||
)
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.alt(
|
||||
IdentifierEntity.grammar.map(identifier => new this({
|
||||
Key: identifier
|
||||
})),
|
||||
Grammar.createEntityGrammar(this)
|
||||
)
|
||||
}
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values, true)
|
||||
constructor() {
|
||||
super()
|
||||
/** @type {String} */ this.ActionName
|
||||
/** @type {Boolean} */ this.bShift
|
||||
/** @type {Boolean} */ this.bCtrl
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { css } from "lit"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P 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"
|
||||
|
||||
@@ -10,42 +9,36 @@ export default class LinearColorEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
R: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
expected: true,
|
||||
}),
|
||||
G: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
expected: true,
|
||||
}),
|
||||
B: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
expected: true,
|
||||
}),
|
||||
A: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(1),
|
||||
}),
|
||||
H: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
ignored: true,
|
||||
}),
|
||||
S: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
ignored: true,
|
||||
}),
|
||||
V: new AttributeInfo({
|
||||
type: ColorChannelEntity,
|
||||
default: () => new ColorChannelEntity(),
|
||||
ignored: true,
|
||||
}),
|
||||
R: ColorChannelEntity.withDefault(),
|
||||
G: ColorChannelEntity.withDefault(),
|
||||
B: ColorChannelEntity.withDefault(),
|
||||
A: ColorChannelEntity.withDefault(type => new type(1)),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this, false)
|
||||
|
||||
#H = new ColorChannelEntity()
|
||||
get H() {
|
||||
return this.#H
|
||||
}
|
||||
set H(value) {
|
||||
this.#H = value
|
||||
}
|
||||
|
||||
#S = new ColorChannelEntity()
|
||||
get S() {
|
||||
return this.#H
|
||||
}
|
||||
set S(value) {
|
||||
this.#H = value
|
||||
}
|
||||
|
||||
#V = new ColorChannelEntity()
|
||||
get V() {
|
||||
return this.#H
|
||||
}
|
||||
set V(value) {
|
||||
this.#H = value
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
/** @param {Number} x */
|
||||
static linearToSRGB(x) {
|
||||
@@ -81,16 +74,13 @@ export default class LinearColorEntity extends IEntity {
|
||||
})
|
||||
}
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this, false)
|
||||
}
|
||||
|
||||
static getLinearColorFromHexGrammar() {
|
||||
return Parsernostrum.regArray(new RegExp(
|
||||
"#(" + Grammar.Regex.HexDigit.source + "{2})"
|
||||
+ "(" + Grammar.Regex.HexDigit.source + "{2})"
|
||||
+ "(" + Grammar.Regex.HexDigit.source + "{2})"
|
||||
+ "(" + Grammar.Regex.HexDigit.source + "{2})?"
|
||||
const hexDigit = /[0-9a-fA-F]/
|
||||
return P.regArray(new RegExp(
|
||||
"#(" + hexDigit.source + "{2})"
|
||||
+ "(" + hexDigit.source + "{2})"
|
||||
+ "(" + hexDigit.source + "{2})"
|
||||
+ "(" + hexDigit.source + "{2})?"
|
||||
)).map(([m, R, G, B, A]) => new this({
|
||||
R: parseInt(R, 16) / 255,
|
||||
G: parseInt(G, 16) / 255,
|
||||
@@ -100,12 +90,12 @@ export default class LinearColorEntity extends IEntity {
|
||||
}
|
||||
|
||||
static getLinearColorRGBListGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.numberByte,
|
||||
return P.seq(
|
||||
P.numberByte,
|
||||
Grammar.commaSeparation,
|
||||
Parsernostrum.numberByte,
|
||||
P.numberByte,
|
||||
Grammar.commaSeparation,
|
||||
Parsernostrum.numberByte,
|
||||
P.numberByte,
|
||||
).map(([R, _1, G, _3, B]) => new this({
|
||||
R: R / 255,
|
||||
G: G / 255,
|
||||
@@ -115,23 +105,23 @@ export default class LinearColorEntity extends IEntity {
|
||||
}
|
||||
|
||||
static getLinearColorRGBGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(/rgb\s*\(\s*/),
|
||||
return P.seq(
|
||||
P.reg(/rgb\s*\(\s*/),
|
||||
this.getLinearColorRGBListGrammar(),
|
||||
Parsernostrum.reg(/\s*\)/)
|
||||
P.reg(/\s*\)/)
|
||||
).map(([_0, linearColor, _2]) => linearColor)
|
||||
}
|
||||
|
||||
static getLinearColorRGBAGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(/rgba\s*\(\s*/),
|
||||
return P.seq(
|
||||
P.reg(/rgba\s*\(\s*/),
|
||||
this.getLinearColorRGBListGrammar(),
|
||||
Parsernostrum.reg(/\s*\)/)
|
||||
P.reg(/\s*\)/)
|
||||
).map(([_0, linearColor, _2]) => linearColor)
|
||||
}
|
||||
|
||||
static getLinearColorFromAnyFormat() {
|
||||
return Parsernostrum.alt(
|
||||
return P.alt(
|
||||
this.getLinearColorFromHexGrammar(),
|
||||
this.getLinearColorRGBAGrammar(),
|
||||
this.getLinearColorRGBGrammar(),
|
||||
@@ -140,6 +130,7 @@ export default class LinearColorEntity extends IEntity {
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
if (values instanceof Array) {
|
||||
values = {
|
||||
R: values[0] ?? 0,
|
||||
@@ -148,14 +139,10 @@ export default class LinearColorEntity extends IEntity {
|
||||
A: values[3] ?? 1,
|
||||
}
|
||||
}
|
||||
super(values)
|
||||
/** @type {ColorChannelEntity} */ this.R
|
||||
/** @type {ColorChannelEntity} */ this.G
|
||||
/** @type {ColorChannelEntity} */ this.B
|
||||
/** @type {ColorChannelEntity} */ this.A
|
||||
/** @type {ColorChannelEntity} */ this.H
|
||||
/** @type {ColorChannelEntity} */ this.S
|
||||
/** @type {ColorChannelEntity} */ this.V
|
||||
this.#updateHSV()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +1,55 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P 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 attributes = {
|
||||
...super.attributes,
|
||||
namespace: AttributeInfo.createValue(""),
|
||||
key: AttributeInfo.createValue(""),
|
||||
value: AttributeInfo.createValue(""),
|
||||
lookbehind: new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: "NSLOCTEXT",
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static lookbehind = "NSLOCTEXT"
|
||||
static grammar = P.regArray(new RegExp(
|
||||
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*`
|
||||
+ String.raw`(?:,\s+)?`
|
||||
+ String.raw`\)`,
|
||||
"m"
|
||||
)).map(matchResult => new this(
|
||||
Utility.unescapeString(matchResult[1]),
|
||||
Utility.unescapeString(matchResult[2]),
|
||||
Utility.unescapeString(matchResult[3]),
|
||||
))
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.regArray(new RegExp(
|
||||
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*`
|
||||
+ String.raw`(?:,\s+)?`
|
||||
+ String.raw`\)`,
|
||||
"m"
|
||||
)).map(matchResult => new this({
|
||||
namespace: Utility.unescapeString(matchResult[1]),
|
||||
key: Utility.unescapeString(matchResult[2]),
|
||||
value: Utility.unescapeString(matchResult[3]),
|
||||
}))
|
||||
#namespace
|
||||
get namespace() {
|
||||
return this.#namespace
|
||||
}
|
||||
set namespace(value) {
|
||||
this.#namespace = value
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {String} */ this.namespace
|
||||
/** @type {String} */ this.key
|
||||
/** @type {String} */ this.value
|
||||
#key
|
||||
get key() {
|
||||
return this.#key
|
||||
}
|
||||
set key(value) {
|
||||
this.#key = value
|
||||
}
|
||||
|
||||
#value
|
||||
get value() {
|
||||
return this.#value
|
||||
}
|
||||
set value(value) {
|
||||
this.#value = value
|
||||
}
|
||||
|
||||
|
||||
constructor(namespace = "", key = "", value = "") {
|
||||
super()
|
||||
this.namespace = namespace
|
||||
this.key = key
|
||||
this.value = value
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
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"
|
||||
@@ -8,24 +7,11 @@ export default class MacroGraphReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
MacroGraph: new AttributeInfo({
|
||||
type: ObjectReferenceEntity,
|
||||
default: () => new ObjectReferenceEntity(),
|
||||
}),
|
||||
GraphBlueprint: new AttributeInfo({
|
||||
type: ObjectReferenceEntity,
|
||||
default: () => new ObjectReferenceEntity(),
|
||||
}),
|
||||
GraphGuid: new AttributeInfo({
|
||||
type: GuidEntity,
|
||||
default: () => new GuidEntity(),
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this)
|
||||
MacroGraph: ObjectReferenceEntity,
|
||||
GraphBlueprint: ObjectReferenceEntity,
|
||||
GraphGuid: GuidEntity,
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
|
||||
@@ -1,36 +1,38 @@
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
/** @template {Attribute} T */
|
||||
export default class MirroredEntity {
|
||||
/** @template {typeof IEntity} T */
|
||||
export default class MirroredEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
type: new AttributeInfo({
|
||||
ignored: true,
|
||||
}),
|
||||
getter: new AttributeInfo({
|
||||
ignored: true,
|
||||
}),
|
||||
}
|
||||
/** @type {typeof IEntity} */
|
||||
static type
|
||||
|
||||
/**
|
||||
* @param {ConstructorType<T>} type
|
||||
* @param {() => T} getter
|
||||
*/
|
||||
constructor(type, getter = null) {
|
||||
this.type = type
|
||||
/** @param {() => T} getter */
|
||||
constructor(getter = null) {
|
||||
super()
|
||||
this.getter = getter
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.getter()
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @param {T} type
|
||||
*/
|
||||
static of(type) {
|
||||
const result = this.asUniqueClass()
|
||||
result.type = type
|
||||
result.grammar = result.getTargetType().grammar.map(v => new this())
|
||||
return result
|
||||
}
|
||||
|
||||
/** @returns {AttributeConstructor<Attribute>} */
|
||||
getTargetType() {
|
||||
/** @returns {typeof IEntity} */
|
||||
static getTargetType() {
|
||||
const result = this.type
|
||||
if (result instanceof MirroredEntity) {
|
||||
return result.getTargetType()
|
||||
if (result.prototype instanceof MirroredEntity) {
|
||||
return /** @type {typeof MirroredEntity} */(result).getTargetType()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.getter().toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import IntegerEntity from "./IntegerEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import Utility from "../Utility.js"
|
||||
import IntegerEntity from "./IntegerEntity.js"
|
||||
|
||||
export default class NaturalNumberEntity extends IntegerEntity {
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = P.numberNatural.map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.numberNatural.map(v => new this(v))
|
||||
set value(value) {
|
||||
value = Math.round(Utility.clamp(this.value, 0))
|
||||
super.value = value
|
||||
}
|
||||
|
||||
constructor(values = 0) {
|
||||
super(values)
|
||||
this.value = Math.round(Utility.clamp(this.value, 0))
|
||||
constructor(value = 0) {
|
||||
super(value)
|
||||
}
|
||||
}
|
||||
|
||||
36
js/entity/NumberEntity.js
Executable file
36
js/entity/NumberEntity.js
Executable file
@@ -0,0 +1,36 @@
|
||||
import P from "parsernostrum"
|
||||
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)`)
|
||||
).map(([_0, n, plusInf, minusInf]) => new this(
|
||||
n ? Number(n) : plusInf ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY
|
||||
))
|
||||
|
||||
/** @type {Number} */
|
||||
#value
|
||||
get value() {
|
||||
return this.#value
|
||||
}
|
||||
set value(value) {
|
||||
if (value === -0) {
|
||||
value = 0
|
||||
}
|
||||
this.#value = value
|
||||
}
|
||||
|
||||
constructor(value = 0) {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value.toString()
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import Configuration from "../Configuration.js"
|
||||
import Utility from "../Utility.js"
|
||||
import nodeColor from "../decoding/nodeColor.js"
|
||||
import nodeIcon from "../decoding/nodeIcon.js"
|
||||
import nodeVariadic from "../decoding/nodeVariadic.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AlternativesEntity from "./AlternativesEntity.js"
|
||||
import ArrayEntity from "./ArrayEntity.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import BooleanEntity from "./BooleanEntity.js"
|
||||
import FunctionReferenceEntity from "./FunctionReferenceEntity.js"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
@@ -13,160 +17,134 @@ import IntegerEntity from "./IntegerEntity.js"
|
||||
import LinearColorEntity from "./LinearColorEntity.js"
|
||||
import MacroGraphReferenceEntity from "./MacroGraphReferenceEntity.js"
|
||||
import MirroredEntity from "./MirroredEntity.js"
|
||||
import NaturalNumberEntity from "./NaturalNumberEntity.js"
|
||||
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
|
||||
import PinEntity from "./PinEntity.js"
|
||||
import ScriptVariableEntity from "./ScriptVariableEntity.js"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
import SymbolEntity from "./SymbolEntity.js"
|
||||
import Union from "./Union.js"
|
||||
import UnknownPinEntity from "./UnknownPinEntity.js"
|
||||
import VariableReferenceEntity from "./VariableReferenceEntity.js"
|
||||
import nodeVariadic from "../decoding/nodeVariadic.js"
|
||||
|
||||
export default class ObjectEntity extends IEntity {
|
||||
|
||||
#_exported = false
|
||||
get _exported() {
|
||||
return this.#_exported
|
||||
}
|
||||
set _exported(value) {
|
||||
this.#_exported = value
|
||||
}
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
isExported: new AttributeInfo({
|
||||
type: Boolean,
|
||||
ignored: true,
|
||||
}),
|
||||
Class: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
Name: AttributeInfo.createType(String),
|
||||
Archetype: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
ExportPath: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
ObjectRef: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
BlueprintElementType: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
BlueprintElementInstance: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
PinTags: new AttributeInfo({
|
||||
type: [null],
|
||||
inlined: true,
|
||||
}),
|
||||
PinNames: new AttributeInfo({
|
||||
type: [String],
|
||||
inlined: true,
|
||||
}),
|
||||
AxisKey: AttributeInfo.createType(SymbolEntity),
|
||||
InputAxisKey: AttributeInfo.createType(SymbolEntity),
|
||||
InputName: AttributeInfo.createType(String),
|
||||
InputType: AttributeInfo.createType(SymbolEntity),
|
||||
NumAdditionalInputs: AttributeInfo.createType(Number),
|
||||
bIsPureFunc: AttributeInfo.createType(Boolean),
|
||||
bIsConstFunc: AttributeInfo.createType(Boolean),
|
||||
bIsCaseSensitive: AttributeInfo.createType(Boolean),
|
||||
VariableReference: AttributeInfo.createType(VariableReferenceEntity),
|
||||
SelfContextInfo: AttributeInfo.createType(SymbolEntity),
|
||||
DelegatePropertyName: AttributeInfo.createType(String),
|
||||
DelegateOwnerClass: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
ComponentPropertyName: AttributeInfo.createType(String),
|
||||
EventReference: AttributeInfo.createType(FunctionReferenceEntity),
|
||||
FunctionReference: AttributeInfo.createType(FunctionReferenceEntity),
|
||||
FunctionScript: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
CustomFunctionName: AttributeInfo.createType(String),
|
||||
TargetType: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MacroGraphReference: AttributeInfo.createType(MacroGraphReferenceEntity),
|
||||
Enum: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
EnumEntries: new AttributeInfo({
|
||||
type: [String],
|
||||
inlined: true,
|
||||
}),
|
||||
InputKey: AttributeInfo.createType(SymbolEntity),
|
||||
OpName: AttributeInfo.createType(String),
|
||||
CachedChangeId: AttributeInfo.createType(GuidEntity),
|
||||
FunctionDisplayName: AttributeInfo.createType(String),
|
||||
AddedPins: new AttributeInfo({
|
||||
type: [UnknownPinEntity],
|
||||
default: () => [],
|
||||
inlined: true,
|
||||
silent: true,
|
||||
}),
|
||||
ChangeId: AttributeInfo.createType(GuidEntity),
|
||||
MaterialFunction: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
bOverrideFunction: AttributeInfo.createType(Boolean),
|
||||
bInternalEvent: AttributeInfo.createType(Boolean),
|
||||
bConsumeInput: AttributeInfo.createType(Boolean),
|
||||
bExecuteWhenPaused: AttributeInfo.createType(Boolean),
|
||||
bOverrideParentBinding: AttributeInfo.createType(Boolean),
|
||||
bControl: AttributeInfo.createType(Boolean),
|
||||
bAlt: AttributeInfo.createType(Boolean),
|
||||
bShift: AttributeInfo.createType(Boolean),
|
||||
bCommand: AttributeInfo.createType(Boolean),
|
||||
CommentColor: AttributeInfo.createType(LinearColorEntity),
|
||||
bCommentBubbleVisible_InDetailsPanel: AttributeInfo.createType(Boolean),
|
||||
bColorCommentBubble: AttributeInfo.createType(Boolean),
|
||||
ProxyFactoryFunctionName: AttributeInfo.createType(String),
|
||||
ProxyFactoryClass: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
ProxyClass: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
StructType: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MaterialExpression: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MaterialExpressionComment: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
MoveMode: AttributeInfo.createType(SymbolEntity),
|
||||
TimelineName: AttributeInfo.createType(String),
|
||||
TimelineGuid: AttributeInfo.createType(GuidEntity),
|
||||
SizeX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
SizeY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
Text: AttributeInfo.createType(new MirroredEntity(String)),
|
||||
MaterialExpressionEditorX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
MaterialExpressionEditorY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
NodeTitle: AttributeInfo.createType(String),
|
||||
NodeTitleColor: AttributeInfo.createType(LinearColorEntity),
|
||||
PositionX: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
PositionY: AttributeInfo.createType(new MirroredEntity(IntegerEntity)),
|
||||
SettingsInterface: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
PCGNode: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
HiGenGridSize: AttributeInfo.createType(SymbolEntity),
|
||||
Operation: AttributeInfo.createType(SymbolEntity),
|
||||
NodePosX: AttributeInfo.createType(IntegerEntity),
|
||||
NodePosY: AttributeInfo.createType(IntegerEntity),
|
||||
NodeHeight: AttributeInfo.createType(IntegerEntity),
|
||||
NodeWidth: AttributeInfo.createType(IntegerEntity),
|
||||
Graph: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
SubgraphInstance: AttributeInfo.createType(String),
|
||||
InputPins: new AttributeInfo({
|
||||
type: [ObjectReferenceEntity],
|
||||
inlined: true,
|
||||
}),
|
||||
OutputPins: new AttributeInfo({
|
||||
type: [ObjectReferenceEntity],
|
||||
inlined: true,
|
||||
}),
|
||||
bExposeToLibrary: AttributeInfo.createType(Boolean),
|
||||
bCanRenameNode: AttributeInfo.createType(Boolean),
|
||||
bCommentBubblePinned: AttributeInfo.createType(Boolean),
|
||||
bCommentBubbleVisible: AttributeInfo.createType(Boolean),
|
||||
NodeComment: AttributeInfo.createType(String),
|
||||
AdvancedPinDisplay: AttributeInfo.createType(IdentifierEntity),
|
||||
DelegateReference: AttributeInfo.createType(VariableReferenceEntity),
|
||||
EnabledState: AttributeInfo.createType(IdentifierEntity),
|
||||
NodeGuid: AttributeInfo.createType(GuidEntity),
|
||||
ErrorType: AttributeInfo.createType(IntegerEntity),
|
||||
ErrorMsg: AttributeInfo.createType(String),
|
||||
ScriptVariables: new AttributeInfo({
|
||||
type: [ScriptVariableEntity],
|
||||
inlined: true,
|
||||
}),
|
||||
Node: AttributeInfo.createType(new MirroredEntity(ObjectReferenceEntity)),
|
||||
ExportedNodes: AttributeInfo.createType(String),
|
||||
CustomProperties: AttributeInfo.createType([new Union(PinEntity, UnknownPinEntity)]),
|
||||
Class: ObjectReferenceEntity,
|
||||
Name: StringEntity,
|
||||
Archetype: ObjectReferenceEntity,
|
||||
ExportPath: ObjectReferenceEntity,
|
||||
ObjectRef: ObjectReferenceEntity,
|
||||
BlueprintElementType: ObjectReferenceEntity,
|
||||
BlueprintElementInstance: ObjectReferenceEntity,
|
||||
PinNames: ArrayEntity.of(StringEntity).flagInlined(),
|
||||
AxisKey: SymbolEntity,
|
||||
InputAxisKey: SymbolEntity,
|
||||
InputName: StringEntity,
|
||||
InputType: SymbolEntity,
|
||||
NumAdditionalInputs: NaturalNumberEntity,
|
||||
bIsPureFunc: BooleanEntity,
|
||||
bIsConstFunc: BooleanEntity,
|
||||
bIsCaseSensitive: BooleanEntity,
|
||||
VariableReference: VariableReferenceEntity,
|
||||
SelfContextInfo: SymbolEntity,
|
||||
DelegatePropertyName: StringEntity,
|
||||
DelegateOwnerClass: ObjectReferenceEntity,
|
||||
ComponentPropertyName: StringEntity,
|
||||
EventReference: FunctionReferenceEntity,
|
||||
FunctionReference: FunctionReferenceEntity,
|
||||
FunctionScript: ObjectReferenceEntity,
|
||||
CustomFunctionName: StringEntity,
|
||||
TargetType: ObjectReferenceEntity,
|
||||
MacroGraphReference: MacroGraphReferenceEntity,
|
||||
Enum: ObjectReferenceEntity,
|
||||
EnumEntries: ArrayEntity.of(StringEntity).flagInlined(),
|
||||
InputKey: SymbolEntity,
|
||||
OpName: StringEntity,
|
||||
CachedChangeId: GuidEntity,
|
||||
FunctionDisplayName: StringEntity,
|
||||
AddedPins: ArrayEntity.of(UnknownPinEntity).withDefault().flagInlined().flagSilent(),
|
||||
ChangeId: GuidEntity,
|
||||
MaterialFunction: ObjectReferenceEntity,
|
||||
bOverrideFunction: BooleanEntity,
|
||||
bInternalEvent: BooleanEntity,
|
||||
bConsumeInput: BooleanEntity,
|
||||
bExecuteWhenPaused: BooleanEntity,
|
||||
bOverrideParentBinding: BooleanEntity,
|
||||
bControl: BooleanEntity,
|
||||
bAlt: BooleanEntity,
|
||||
bShift: BooleanEntity,
|
||||
bCommand: BooleanEntity,
|
||||
CommentColor: LinearColorEntity,
|
||||
bCommentBubbleVisible_InDetailsPanel: BooleanEntity,
|
||||
bColorCommentBubble: BooleanEntity,
|
||||
ProxyFactoryFunctionName: StringEntity,
|
||||
ProxyFactoryClass: ObjectReferenceEntity,
|
||||
ProxyClass: ObjectReferenceEntity,
|
||||
StructType: ObjectReferenceEntity,
|
||||
MaterialExpression: ObjectReferenceEntity,
|
||||
MaterialExpressionComment: ObjectReferenceEntity,
|
||||
MoveMode: SymbolEntity,
|
||||
TimelineName: StringEntity,
|
||||
TimelineGuid: GuidEntity,
|
||||
SizeX: MirroredEntity.of(IntegerEntity),
|
||||
SizeY: MirroredEntity.of(IntegerEntity),
|
||||
Text: MirroredEntity.of(StringEntity),
|
||||
MaterialExpressionEditorX: MirroredEntity.of(IntegerEntity),
|
||||
MaterialExpressionEditorY: MirroredEntity.of(IntegerEntity),
|
||||
NodeTitle: StringEntity,
|
||||
NodeTitleColor: LinearColorEntity,
|
||||
PositionX: MirroredEntity.of(IntegerEntity),
|
||||
PositionY: MirroredEntity.of(IntegerEntity),
|
||||
SettingsInterface: ObjectReferenceEntity,
|
||||
PCGNode: ObjectReferenceEntity,
|
||||
HiGenGridSize: SymbolEntity,
|
||||
Operation: SymbolEntity,
|
||||
NodePosX: IntegerEntity,
|
||||
NodePosY: IntegerEntity,
|
||||
NodeHeight: IntegerEntity,
|
||||
NodeWidth: IntegerEntity,
|
||||
Graph: ObjectReferenceEntity,
|
||||
SubgraphInstance: StringEntity,
|
||||
InputPins: ArrayEntity.of(ObjectReferenceEntity).flagInlined(),
|
||||
OutputPins: ArrayEntity.of(ObjectReferenceEntity).flagInlined(),
|
||||
bExposeToLibrary: BooleanEntity,
|
||||
bCanRenameNode: BooleanEntity,
|
||||
bCommentBubblePinned: BooleanEntity,
|
||||
bCommentBubbleVisible: BooleanEntity,
|
||||
NodeComment: StringEntity,
|
||||
AdvancedPinDisplay: IdentifierEntity,
|
||||
DelegateReference: VariableReferenceEntity,
|
||||
EnabledState: IdentifierEntity,
|
||||
NodeGuid: GuidEntity,
|
||||
ErrorType: IntegerEntity,
|
||||
ErrorMsg: StringEntity,
|
||||
ScriptVariables: ArrayEntity.of(ScriptVariableEntity),
|
||||
Node: MirroredEntity.of(ObjectReferenceEntity),
|
||||
ExportedNodes: StringEntity,
|
||||
CustomProperties: ArrayEntity.of(AlternativesEntity.accepting(PinEntity, UnknownPinEntity)),
|
||||
}
|
||||
static nameRegex = /^(\w+?)(?:_(\d+))?$/
|
||||
static customPropertyGrammar = Parsernostrum.seq(
|
||||
Parsernostrum.reg(/CustomProperties\s+/),
|
||||
Grammar.grammarFor(
|
||||
undefined,
|
||||
this.attributes.CustomProperties.type[0]
|
||||
),
|
||||
static #nameRegex = /^(\w+?)(?:_(\d+))?$/
|
||||
static customPropertyGrammar = P.seq(
|
||||
P.reg(/CustomProperties\s+/),
|
||||
this.attributes.CustomProperties.type.grammar,
|
||||
).map(([_0, pin]) => values => {
|
||||
if (!values.CustomProperties) {
|
||||
values.CustomProperties = []
|
||||
}
|
||||
values.CustomProperties.push(pin)
|
||||
(values.CustomProperties ??= []).push(pin)
|
||||
})
|
||||
static inlinedArrayEntryGrammar = Parsernostrum.seq(
|
||||
Parsernostrum.alt(
|
||||
static inlinedArrayEntryGrammar = P.seq(
|
||||
P.alt(
|
||||
Grammar.symbolQuoted.map(v => [v, true]),
|
||||
Grammar.symbol.map(v => [v, false]),
|
||||
),
|
||||
Parsernostrum.reg(
|
||||
P.reg(
|
||||
new RegExp(`\\s*\\(\\s*(\\d+)\\s*\\)\\s*\\=\\s*`),
|
||||
1
|
||||
).map(Number)
|
||||
@@ -192,21 +170,21 @@ export default class ObjectEntity extends IEntity {
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createSubObjectGrammar() {
|
||||
return Parsernostrum.lazy(() => this.grammar)
|
||||
return P.lazy(() => this.grammar)
|
||||
.map(object =>
|
||||
values => values[Configuration.subObjectAttributeNameFromEntity(object)] = object
|
||||
)
|
||||
}
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(/Begin +Object/),
|
||||
Parsernostrum.seq(
|
||||
Parsernostrum.whitespace,
|
||||
Parsernostrum.alt(
|
||||
return P.seq(
|
||||
P.reg(/Begin +Object/),
|
||||
P.seq(
|
||||
P.whitespace,
|
||||
P.alt(
|
||||
this.createSubObjectGrammar(),
|
||||
this.customPropertyGrammar,
|
||||
Grammar.createAttributeGrammar(this, Parsernostrum.reg(Grammar.Regex.MultipleWordsSymbols)),
|
||||
Grammar.createAttributeGrammar(this, P.reg(Grammar.Regex.MultipleWordsSymbols)),
|
||||
Grammar.createAttributeGrammar(this, Grammar.attributeNameQuoted, undefined, (obj, k, v) =>
|
||||
Utility.objectSet(obj, ["attributes", ...k, "quoted"], true)
|
||||
),
|
||||
@@ -215,7 +193,7 @@ export default class ObjectEntity extends IEntity {
|
||||
)
|
||||
.map(([_0, entry]) => entry)
|
||||
.many(),
|
||||
Parsernostrum.reg(/\s+End +Object/),
|
||||
P.reg(/\s+End +Object/),
|
||||
)
|
||||
.map(([_0, attributes, _2]) => {
|
||||
const values = {}
|
||||
@@ -225,16 +203,16 @@ export default class ObjectEntity extends IEntity {
|
||||
}
|
||||
|
||||
static getMultipleObjectsGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.whitespaceOpt,
|
||||
return P.seq(
|
||||
P.whitespaceOpt,
|
||||
this.grammar,
|
||||
Parsernostrum.seq(
|
||||
Parsernostrum.whitespace,
|
||||
P.seq(
|
||||
P.whitespace,
|
||||
this.grammar,
|
||||
)
|
||||
.map(([_0, object]) => object)
|
||||
.many(),
|
||||
Parsernostrum.whitespaceOpt
|
||||
P.whitespaceOpt
|
||||
)
|
||||
.map(([_0, first, remaining, _4]) => [first, ...remaining])
|
||||
}
|
||||
@@ -242,7 +220,7 @@ export default class ObjectEntity extends IEntity {
|
||||
/** @type {String} */
|
||||
#class
|
||||
|
||||
constructor(values = {}, suppressWarns = false) {
|
||||
constructor(values = {}) {
|
||||
if ("NodePosX" in values !== "NodePosY" in values) {
|
||||
const entries = Object.entries(values)
|
||||
const [key, position] = "NodePosX" in values
|
||||
@@ -252,13 +230,7 @@ export default class ObjectEntity extends IEntity {
|
||||
entries.splice(position, 0, entry)
|
||||
values = Object.fromEntries(entries)
|
||||
}
|
||||
super(values, suppressWarns)
|
||||
|
||||
// Attributes not assigned a strong type in attributes because the names are too generic
|
||||
/** @type {Number | MirroredEntity<Boolean>} */ this.R
|
||||
/** @type {Number | MirroredEntity<Boolean>} */ this.G
|
||||
/** @type {Number | MirroredEntity<Boolean>} */ this.B
|
||||
/** @type {Number | MirroredEntity<Boolean>} */ this.A
|
||||
super(values)
|
||||
|
||||
// Attributes
|
||||
/** @type {(PinEntity | UnknownPinEntity)[]} */ this.CustomProperties
|
||||
@@ -359,19 +331,19 @@ export default class ObjectEntity extends IEntity {
|
||||
this.getPinEntities().find(pin => pin.PinName === pinName && (pin.recomputesNodeTitleOnChange = true))
|
||||
)
|
||||
const attribute = {}
|
||||
obj.R = new MirroredEntity(Boolean, () => rgbaPins[0].DefaultValue)
|
||||
obj.G = new MirroredEntity(Boolean, () => rgbaPins[1].DefaultValue)
|
||||
obj.B = new MirroredEntity(Boolean, () => rgbaPins[2].DefaultValue)
|
||||
obj.A = new MirroredEntity(Boolean, () => rgbaPins[3].DefaultValue)
|
||||
Utility.objectSet(obj, ["attributes", "R", "default"], false)
|
||||
Utility.objectSet(obj, ["attributes", "R", "silent"], true)
|
||||
Utility.objectSet(obj, ["attributes", "G", "default"], false)
|
||||
Utility.objectSet(obj, ["attributes", "G", "silent"], true)
|
||||
Utility.objectSet(obj, ["attributes", "B", "default"], false)
|
||||
Utility.objectSet(obj, ["attributes", "B", "silent"], true)
|
||||
Utility.objectSet(obj, ["attributes", "A", "default"], false)
|
||||
Utility.objectSet(obj, ["attributes", "A", "silent"], true)
|
||||
obj._keys = [...Configuration.rgba, ...Object.keys(obj).filter(k => !Configuration.rgba.includes(k))]
|
||||
obj.R = new (
|
||||
MirroredEntity.of(BooleanEntity).withDefault().flagSilent()
|
||||
)(() => rgbaPins[0].DefaultValue)
|
||||
obj.G = new (
|
||||
MirroredEntity.of(BooleanEntity).withDefault().flagSilent()
|
||||
)(() => rgbaPins[1].DefaultValue)
|
||||
obj.B = new (
|
||||
MirroredEntity.of(BooleanEntity).withDefault().flagSilent()
|
||||
)(() => rgbaPins[2].DefaultValue)
|
||||
obj.A = new (
|
||||
MirroredEntity.of(BooleanEntity).withDefault().flagSilent()
|
||||
)(() => rgbaPins[3].DefaultValue)
|
||||
obj.keys = [...Configuration.rgba, ...super.keys.filter(k => !Configuration.rgba.includes(k))]
|
||||
}
|
||||
}
|
||||
/** @type {ObjectEntity} */
|
||||
@@ -388,10 +360,10 @@ export default class ObjectEntity extends IEntity {
|
||||
nodeRef.type === this.PCGNode.type
|
||||
&& nodeRef.path === `${this.Name}.${this.PCGNode.path}`
|
||||
) {
|
||||
obj.Node.getter = () => new ObjectReferenceEntity({
|
||||
type: this.PCGNode.type,
|
||||
path: `${this.Name}.${this.PCGNode.path}`,
|
||||
})
|
||||
obj.Node.getter = () => new ObjectReferenceEntity(
|
||||
this.PCGNode.type,
|
||||
`${this.Name}.${this.PCGNode.path}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,7 +418,7 @@ export default class ObjectEntity extends IEntity {
|
||||
|
||||
/** @returns {[String, Number]} */
|
||||
getNameAndCounter() {
|
||||
const result = this.getObjectName().match(ObjectEntity.nameRegex)
|
||||
const result = this.getObjectName().match(ObjectEntity.#nameRegex)
|
||||
let name = ""
|
||||
let counter = null
|
||||
return result
|
||||
|
||||
@@ -1,73 +1,71 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P 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 ObjectReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
type: new AttributeInfo({
|
||||
default: "",
|
||||
serialized: true,
|
||||
}),
|
||||
path: new AttributeInfo({
|
||||
default: "",
|
||||
serialized: true,
|
||||
}),
|
||||
_full: new AttributeInfo({
|
||||
ignored: true,
|
||||
}),
|
||||
}
|
||||
static quoted = Parsernostrum.regArray(new RegExp(
|
||||
static #quotedParser = P.regArray(new RegExp(
|
||||
`'"(${Grammar.Regex.InsideString.source})"'`
|
||||
+ "|"
|
||||
+ `'(${Grammar.Regex.InsideSingleQuotedString.source})'`
|
||||
)).map(([_0, a, b]) => a ?? b)
|
||||
static path = this.quoted.getParser().parser.regexp.source + "|" + Grammar.Regex.Path.source
|
||||
static typeReference = Parsernostrum.reg(
|
||||
static typeReference = P.reg(
|
||||
new RegExp(Grammar.Regex.Path.source + "|" + Grammar.symbol.getParser().regexp.source)
|
||||
)
|
||||
static fullReferenceGrammar = Parsernostrum.regArray(
|
||||
static fullReferenceGrammar = P.regArray(
|
||||
new RegExp(
|
||||
"(" + this.typeReference.getParser().regexp.source + ")"
|
||||
+ "(?:" + this.quoted.getParser().parser.regexp.source + ")"
|
||||
+ "(?:" + this.#quotedParser.getParser().parser.regexp.source + ")"
|
||||
)
|
||||
).map(([_full, type, ...path]) => new this({ type, path: path.find(v => v), _full }))
|
||||
static fullReferenceSerializedGrammar = Parsernostrum.regArray(
|
||||
).map(([full, type, ...path]) => new this(type, path.find(v => v), full))
|
||||
static fullReferenceSerializedGrammar = P.regArray(
|
||||
new RegExp(
|
||||
'"(' + Grammar.Regex.InsideString.source + "?)"
|
||||
+ "(?:'(" + Grammar.Regex.InsideSingleQuotedString.source + `?)')?"`
|
||||
)
|
||||
).map(([_full, type, path]) => new this({ type, path, _full }))
|
||||
static typeReferenceGrammar = this.typeReference.map(v => new this({ type: v, path: "", _full: v }))
|
||||
static grammar = this.createGrammar()
|
||||
).map(([full, type, path]) => new this(type, path, full))
|
||||
static typeReferenceGrammar = this.typeReference.map(v => new this(v, "", v))
|
||||
static grammar = P.alt(
|
||||
this.fullReferenceSerializedGrammar,
|
||||
this.fullReferenceGrammar,
|
||||
this.typeReferenceGrammar,
|
||||
)
|
||||
|
||||
constructor(values = {}) {
|
||||
if (values.constructor === String) {
|
||||
values = {
|
||||
path: values
|
||||
}
|
||||
}
|
||||
super(values)
|
||||
if (!values._full || values._full.length === 0) {
|
||||
this._full = `"${this.type + (this.path ? (`'${this.path}'`) : "")}"`
|
||||
}
|
||||
/** @type {String} */ this.type
|
||||
/** @type {String} */ this.path
|
||||
#type
|
||||
get type() {
|
||||
return this.#type
|
||||
}
|
||||
set type(value) {
|
||||
this.#type = value
|
||||
}
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.alt(
|
||||
this.fullReferenceSerializedGrammar,
|
||||
this.fullReferenceGrammar,
|
||||
this.typeReferenceGrammar,
|
||||
)
|
||||
#path
|
||||
get path() {
|
||||
return this.#path
|
||||
}
|
||||
set path(value) {
|
||||
this.#path = value
|
||||
}
|
||||
|
||||
#full
|
||||
get full() {
|
||||
return this.#full
|
||||
}
|
||||
set full(value) {
|
||||
this.#full = value
|
||||
}
|
||||
|
||||
|
||||
constructor(type = "None", path = "", full = null) {
|
||||
super()
|
||||
this.#type = type
|
||||
this.#path = path
|
||||
this.#full = full ?? `"${this.type + (this.path ? (`'${this.path}'`) : "")}"`
|
||||
}
|
||||
|
||||
static createNoneInstance() {
|
||||
return new ObjectReferenceEntity({ type: "None", path: "" })
|
||||
return new ObjectReferenceEntity("None")
|
||||
}
|
||||
|
||||
getName(dropCounter = false) {
|
||||
@@ -75,6 +73,6 @@ export default class ObjectReferenceEntity extends IEntity {
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this._full
|
||||
return this.full
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,13 @@
|
||||
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: new AttributeInfo({
|
||||
default: "",
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = Grammar.symbol.map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.symbol.map(v => new this(v))
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
if (values.constructor !== Object) {
|
||||
values = {
|
||||
value: values,
|
||||
}
|
||||
}
|
||||
super(values)
|
||||
/** @type {String} */ this.value
|
||||
constructor(value = "") {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
@@ -31,6 +15,6 @@ export default class PathSymbolEntity extends IEntity {
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value
|
||||
return this.value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@ import Configuration from "../Configuration.js"
|
||||
import pinColor from "../decoding/pinColor.js"
|
||||
import pinTitle from "../decoding/pinTitle.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import AlternativesEntity from "./AlternativesEntity.js"
|
||||
import ArrayEntity from "./ArrayEntity.js"
|
||||
import BooleanEntity from "./BooleanEntity.js"
|
||||
import ByteEntity from "./ByteEntity.js"
|
||||
import ComputedType from "./ComputedType.js"
|
||||
import ComputedTypeEntity from "./ComputedTypeEntity.js"
|
||||
import EnumDisplayValueEntity from "./EnumDisplayValueEntity.js"
|
||||
import EnumEntity from "./EnumEntity.js"
|
||||
import FormatTextEntity from "./FormatTextEntity.js"
|
||||
@@ -15,6 +17,7 @@ import IntegerEntity from "./IntegerEntity.js"
|
||||
import InvariantTextEntity from "./InvariantTextEntity.js"
|
||||
import LinearColorEntity from "./LinearColorEntity.js"
|
||||
import LocalizedTextEntity from "./LocalizedTextEntity.js"
|
||||
import NumberEntity from "./NumberEntity.js"
|
||||
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
|
||||
import PinReferenceEntity from "./PinReferenceEntity.js"
|
||||
import PinTypeEntity from "./PinTypeEntity.js"
|
||||
@@ -24,7 +27,7 @@ import SimpleSerializationRotatorEntity from "./SimpleSerializationRotatorEntity
|
||||
import SimpleSerializationVector2DEntity from "./SimpleSerializationVector2DEntity.js"
|
||||
import SimpleSerializationVector4DEntity from "./SimpleSerializationVector4DEntity.js"
|
||||
import SimpleSerializationVectorEntity from "./SimpleSerializationVectorEntity.js"
|
||||
import Union from "./Union.js"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
import Vector2DEntity from "./Vector2DEntity.js"
|
||||
import Vector4DEntity from "./Vector4DEntity.js"
|
||||
import VectorEntity from "./VectorEntity.js"
|
||||
@@ -32,21 +35,22 @@ import VectorEntity from "./VectorEntity.js"
|
||||
/** @template {TerminalAttribute} T */
|
||||
export default class PinEntity extends IEntity {
|
||||
|
||||
static lookbehind = "INVTEXT"
|
||||
static #typeEntityMap = {
|
||||
[Configuration.paths.linearColor]: LinearColorEntity,
|
||||
[Configuration.paths.rotator]: RotatorEntity,
|
||||
[Configuration.paths.vector]: VectorEntity,
|
||||
[Configuration.paths.vector2D]: Vector2DEntity,
|
||||
[Configuration.paths.vector4f]: Vector4DEntity,
|
||||
"bool": Boolean,
|
||||
"bool": BooleanEntity,
|
||||
"byte": ByteEntity,
|
||||
"enum": EnumEntity,
|
||||
"exec": String,
|
||||
"exec": StringEntity,
|
||||
"int": IntegerEntity,
|
||||
"int64": Integer64Entity,
|
||||
"name": String,
|
||||
"real": Number,
|
||||
"string": String,
|
||||
"name": StringEntity,
|
||||
"real": NumberEntity,
|
||||
"string": StringEntity,
|
||||
}
|
||||
static #alternativeTypeEntityMap = {
|
||||
"enum": EnumDisplayValueEntity,
|
||||
@@ -59,51 +63,36 @@ export default class PinEntity extends IEntity {
|
||||
}
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
lookbehind: new AttributeInfo({
|
||||
default: "Pin",
|
||||
ignored: true,
|
||||
}),
|
||||
objectEntity: new AttributeInfo({
|
||||
ignored: true,
|
||||
}),
|
||||
pinIndex: new AttributeInfo({
|
||||
type: Number,
|
||||
ignored: true,
|
||||
}),
|
||||
PinId: new AttributeInfo({
|
||||
type: GuidEntity,
|
||||
default: () => new GuidEntity()
|
||||
}),
|
||||
PinName: AttributeInfo.createValue(""),
|
||||
PinFriendlyName: AttributeInfo.createType(new Union(LocalizedTextEntity, FormatTextEntity, InvariantTextEntity, String)),
|
||||
PinToolTip: AttributeInfo.createType(String),
|
||||
Direction: AttributeInfo.createType(String),
|
||||
PinType: new AttributeInfo({
|
||||
type: PinTypeEntity,
|
||||
default: () => new PinTypeEntity(),
|
||||
inlined: true,
|
||||
}),
|
||||
LinkedTo: AttributeInfo.createType([PinReferenceEntity]),
|
||||
SubPins: AttributeInfo.createType([PinReferenceEntity]),
|
||||
ParentPin: AttributeInfo.createType(PinReferenceEntity),
|
||||
DefaultValue: new AttributeInfo({
|
||||
type: new ComputedType(
|
||||
PinId: GuidEntity.withDefault(),
|
||||
PinName: StringEntity.withDefault(),
|
||||
PinFriendlyName: AlternativesEntity.accepting(
|
||||
LocalizedTextEntity,
|
||||
FormatTextEntity,
|
||||
InvariantTextEntity,
|
||||
StringEntity
|
||||
),
|
||||
PinToolTip: StringEntity,
|
||||
Direction: StringEntity,
|
||||
PinType: PinTypeEntity.withDefault().flagInlined(),
|
||||
LinkedTo: ArrayEntity.of(PinReferenceEntity),
|
||||
SubPins: ArrayEntity.of(PinReferenceEntity),
|
||||
ParentPin: PinReferenceEntity,
|
||||
DefaultValue:
|
||||
ComputedTypeEntity.from(
|
||||
/** @param {PinEntity} pinEntity */
|
||||
pinEntity => pinEntity.getEntityType(true) ?? String
|
||||
),
|
||||
serialized: true,
|
||||
}),
|
||||
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),
|
||||
pinEntity => pinEntity.getEntityType(true) ?? StringEntity
|
||||
).flagSerialized(),
|
||||
AutogeneratedDefaultValue: StringEntity,
|
||||
DefaultObject: ObjectReferenceEntity,
|
||||
PersistentGuid: GuidEntity,
|
||||
bHidden: BooleanEntity.withDefault(),
|
||||
bNotConnectable: BooleanEntity.withDefault(),
|
||||
bDefaultValueIsReadOnly: BooleanEntity.withDefault(),
|
||||
bDefaultValueIsIgnored: BooleanEntity.withDefault(),
|
||||
bAdvancedView: BooleanEntity.withDefault(),
|
||||
bOrphanedPin: BooleanEntity.withDefault(),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
|
||||
#recomputesNodeTitleOnChange = false
|
||||
set recomputesNodeTitleOnChange(value) {
|
||||
@@ -113,12 +102,24 @@ export default class PinEntity extends IEntity {
|
||||
return this.#recomputesNodeTitleOnChange
|
||||
}
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this)
|
||||
#objectEntity
|
||||
get objectEntity() {
|
||||
return this.#objectEntity
|
||||
}
|
||||
set objectEntity(value) {
|
||||
this.#objectEntity = value
|
||||
}
|
||||
|
||||
constructor(values = {}, suppressWarns = false) {
|
||||
super(values, suppressWarns)
|
||||
#pinIndex
|
||||
get pinIndex() {
|
||||
return this.#pinIndex
|
||||
}
|
||||
set pinIndex(value) {
|
||||
this.#pinIndex = value
|
||||
}
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
/** @type {ObjectEntity} */ this.objectEntity
|
||||
/** @type {Number} */ this.pinIndex
|
||||
/** @type {GuidEntity} */ this.PinId
|
||||
@@ -142,7 +143,7 @@ export default class PinEntity extends IEntity {
|
||||
|
||||
/** @param {ObjectEntity} objectEntity */
|
||||
static fromLegacyObject(objectEntity) {
|
||||
return new PinEntity(objectEntity, true)
|
||||
return new PinEntity(objectEntity)
|
||||
}
|
||||
|
||||
getType() {
|
||||
|
||||
@@ -1,34 +1,23 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import PathSymbolEntity from "./PathSymbolEntity.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
|
||||
export default class PinReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
objectName: AttributeInfo.createType(PathSymbolEntity),
|
||||
pinGuid: AttributeInfo.createType(GuidEntity),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = P.seq(
|
||||
PathSymbolEntity.grammar,
|
||||
P.whitespace,
|
||||
GuidEntity.grammar
|
||||
).map(([objectName, _1, pinGuid]) => new this(objectName, pinGuid))
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
PathSymbolEntity.grammar,
|
||||
Parsernostrum.whitespace,
|
||||
GuidEntity.grammar
|
||||
).map(
|
||||
([objectName, _1, pinGuid]) => new this({
|
||||
objectName: objectName,
|
||||
pinGuid: pinGuid,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {PathSymbolEntity} */ this.objectName
|
||||
/** @type {GuidEntity} */ this.pinGuid
|
||||
/**
|
||||
* @param {PathSymbolEntity} objectName
|
||||
* @param {GuidEntity} pinGuid
|
||||
*/
|
||||
constructor(objectName = null, pinGuid = null) {
|
||||
super()
|
||||
this.objectName = objectName
|
||||
this.pinGuid = pinGuid
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,31 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
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"
|
||||
|
||||
export default class PinTypeEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
PinCategory: AttributeInfo.createValue(""),
|
||||
PinSubCategory: AttributeInfo.createValue(""),
|
||||
PinSubCategoryObject: new AttributeInfo({
|
||||
type: ObjectReferenceEntity,
|
||||
default: () => ObjectReferenceEntity.createNoneInstance(),
|
||||
}),
|
||||
PinSubCategoryMemberReference: new AttributeInfo({
|
||||
type: FunctionReferenceEntity,
|
||||
default: null,
|
||||
}),
|
||||
PinValueType: new AttributeInfo({
|
||||
type: PinTypeEntity,
|
||||
default: null,
|
||||
}),
|
||||
ContainerType: AttributeInfo.createType(PathSymbolEntity),
|
||||
bIsReference: AttributeInfo.createValue(false),
|
||||
bIsConst: AttributeInfo.createValue(false),
|
||||
bIsWeakPointer: AttributeInfo.createValue(false),
|
||||
bIsUObjectWrapper: AttributeInfo.createValue(false),
|
||||
bSerializeAsSinglePrecisionFloat: AttributeInfo.createValue(false),
|
||||
PinCategory: StringEntity.withDefault(),
|
||||
PinSubCategory: StringEntity.withDefault(),
|
||||
PinSubCategoryObject: ObjectReferenceEntity.withDefault(),
|
||||
PinSubCategoryMemberReference: FunctionReferenceEntity.withDefault(type => null),
|
||||
PinValueType: PinTypeEntity.withDefault(),
|
||||
ContainerType: PathSymbolEntity,
|
||||
bIsReference: BooleanEntity.withDefault(),
|
||||
bIsConst: BooleanEntity.withDefault(),
|
||||
bIsWeakPointer: BooleanEntity.withDefault(),
|
||||
bIsUObjectWrapper: BooleanEntity.withDefault(),
|
||||
bSerializeAsSinglePrecisionFloat: BooleanEntity.withDefault(),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this)
|
||||
}
|
||||
|
||||
constructor(values = {}, suppressWarns = false) {
|
||||
super(values, suppressWarns)
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
/** @type {String} */ this.PinCategory
|
||||
/** @type {String} */ this.PinSubCategory
|
||||
/** @type {ObjectReferenceEntity} */ this.PinSubCategoryObject
|
||||
@@ -54,16 +42,10 @@ export default class PinTypeEntity extends IEntity {
|
||||
|
||||
/** @param {PinTypeEntity} other */
|
||||
copyTypeFrom(other) {
|
||||
this.PinCategory = other.PinCategory
|
||||
this.PinSubCategory = other.PinSubCategory
|
||||
this.PinSubCategoryObject = other.PinSubCategoryObject
|
||||
this.PinSubCategoryMemberReference = other.PinSubCategoryMemberReference
|
||||
this.PinValueType = other.PinValueType
|
||||
this.ContainerType = other.ContainerType
|
||||
this.bIsReference = other.bIsReference
|
||||
this.bIsConst = other.bIsConst
|
||||
this.bIsWeakPointer = other.bIsWeakPointer
|
||||
this.bIsUObjectWrapper = other.bIsUObjectWrapper
|
||||
this.bSerializeAsSinglePrecisionFloat = other.bSerializeAsSinglePrecisionFloat
|
||||
for (const key of this.keys) {
|
||||
if (other[key] !== undefined) {
|
||||
this[key] = other[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import Vector2DEntity from "./Vector2DEntity.js"
|
||||
|
||||
export default class RBSerializationVector2DEntity extends Vector2DEntity {
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.alt(
|
||||
Parsernostrum.regArray(new RegExp(
|
||||
/X\s*=\s*/.source + "(?<x>" + Parsernostrum.number.getParser().parser.regexp.source + ")"
|
||||
+ "\\s+"
|
||||
+ /Y\s*=\s*/.source + "(?<y>" + Parsernostrum.number.getParser().parser.regexp.source + ")"
|
||||
)).map(({ groups: { x, y } }) => new this({
|
||||
X: Number(x),
|
||||
Y: Number(y),
|
||||
})),
|
||||
Vector2DEntity.grammar
|
||||
)
|
||||
}
|
||||
static grammar = P.alt(
|
||||
P.regArray(new RegExp(
|
||||
/X\s*=\s*/.source + "(?<x>" + P.number.getParser().parser.regexp.source + ")"
|
||||
+ "\\s+"
|
||||
+ /Y\s*=\s*/.source + "(?<y>" + P.number.getParser().parser.regexp.source + ")"
|
||||
)).map(({ groups: { x, y } }) => new this({
|
||||
X: Number(x),
|
||||
Y: Number(y),
|
||||
})),
|
||||
Vector2DEntity.grammar
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,35 +1,22 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import NumberEntity from "./NumberEntity.js"
|
||||
|
||||
export default class RotatorEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
R: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
P: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
Y: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this, false)
|
||||
R: NumberEntity.withDefault(),
|
||||
P: NumberEntity.withDefault(),
|
||||
Y: NumberEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this, false)
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {Number} */ this.R
|
||||
/** @type {Number} */ this.P
|
||||
/** @type {Number} */ this.Y
|
||||
/** @type {NumberEntity} */ this.R
|
||||
/** @type {NumberEntity} */ this.P
|
||||
/** @type {NumberEntity} */ this.Y
|
||||
}
|
||||
|
||||
getRoll() {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
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"
|
||||
@@ -8,17 +7,13 @@ export default class ScriptVariableEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
ScriptVariable: AttributeInfo.createType(ObjectReferenceEntity),
|
||||
OriginalChangeId: AttributeInfo.createType(GuidEntity),
|
||||
ScriptVariable: ObjectReferenceEntity,
|
||||
OriginalChangeId: GuidEntity,
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this)
|
||||
}
|
||||
|
||||
constructor(values = {}, suppressWarns = false) {
|
||||
super(values, suppressWarns)
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
/** @type {ObjectReferenceEntity} */ this.ScriptVariable
|
||||
/** @type {GuidEntity} */ this.OriginalChangeId
|
||||
}
|
||||
|
||||
@@ -1,25 +1,20 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import RotatorEntity from "./RotatorEntity.js"
|
||||
|
||||
export default class SimpleSerializationRotatorEntity extends RotatorEntity {
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
const number = Parsernostrum.number.getParser().parser.regexp.source
|
||||
return Parsernostrum.alt(
|
||||
Parsernostrum.regArray(new RegExp(
|
||||
"(" + number + ")"
|
||||
+ "\\s*,\\s*"
|
||||
+ "(" + number + ")"
|
||||
+ "\\s*,\\s*"
|
||||
+ "(" + number + ")"
|
||||
)).map(([_, p, y, r]) => new this({
|
||||
R: Number(r),
|
||||
P: Number(p),
|
||||
Y: Number(y),
|
||||
})),
|
||||
RotatorEntity.grammar
|
||||
)
|
||||
}
|
||||
static grammar = P.alt(
|
||||
P.regArray(new RegExp(
|
||||
`(${P.number.getParser().parser.regexp.source})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
)).map(([_, p, y, r]) => new this({
|
||||
R: Number(r),
|
||||
P: Number(p),
|
||||
Y: Number(y),
|
||||
})),
|
||||
RotatorEntity.grammar
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import Vector2DEntity from "./Vector2DEntity.js"
|
||||
|
||||
export default class SimpleSerializationVector2DEntity extends Vector2DEntity {
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
const number = Parsernostrum.number.getParser().parser.regexp.source
|
||||
return Parsernostrum.alt(
|
||||
Parsernostrum.regArray(new RegExp(
|
||||
"(" + number + ")"
|
||||
+ "\\s*,\\s*"
|
||||
+ "(" + number + ")"
|
||||
)).map(([_, x, y]) => new this({
|
||||
X: Number(x),
|
||||
Y: Number(y),
|
||||
})),
|
||||
Vector2DEntity.grammar
|
||||
)
|
||||
}
|
||||
static grammar = P.alt(
|
||||
P.regArray(new RegExp(
|
||||
`(${P.number.getParser().parser.regexp.source})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
)).map(([_, x, y]) => new this({
|
||||
X: Number(x),
|
||||
Y: Number(y),
|
||||
})),
|
||||
Vector2DEntity.grammar
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import Vector4DEntity from "./Vector4DEntity.js"
|
||||
|
||||
export default class SimpleSerializationVector4DEntity extends Vector4DEntity {
|
||||
@@ -6,16 +6,16 @@ export default class SimpleSerializationVector4DEntity extends Vector4DEntity {
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
const number = Parsernostrum.number.getParser().parser.regexp.source
|
||||
return Parsernostrum.alt(
|
||||
Parsernostrum.regArray(new RegExp(
|
||||
"(" + number + ")"
|
||||
+ "\\s*,\\s*"
|
||||
+ "(" + number + ")"
|
||||
+ "\\s*,\\s*"
|
||||
+ "(" + number + ")"
|
||||
+ "\\s*,\\s*"
|
||||
+ "(" + number + ")"
|
||||
const number = P.number.getParser().parser.regexp.source
|
||||
return P.alt(
|
||||
P.regArray(new RegExp(
|
||||
`(${P.number.getParser().parser.regexp.source})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
))
|
||||
.map(([_0, x, y, z, w]) => new this({
|
||||
X: Number(x),
|
||||
|
||||
@@ -1,26 +1,21 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P from "parsernostrum"
|
||||
import VectorEntity from "./VectorEntity.js"
|
||||
|
||||
export default class SimpleSerializationVectorEntity extends VectorEntity {
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
const number = Parsernostrum.number.getParser().parser.regexp.source
|
||||
return Parsernostrum.alt(
|
||||
Parsernostrum.regArray(new RegExp(
|
||||
"(" + number + ")"
|
||||
+ "\\s*,\\s*"
|
||||
+ "(" + number + ")"
|
||||
+ "\\s*,\\s*"
|
||||
+ "(" + number + ")"
|
||||
))
|
||||
.map(([_0, x, y, z]) => new this({
|
||||
X: Number(x),
|
||||
Y: Number(y),
|
||||
Z: Number(z),
|
||||
})),
|
||||
VectorEntity.grammar
|
||||
)
|
||||
}
|
||||
static grammar = P.alt(
|
||||
P.regArray(new RegExp(
|
||||
`(${P.number.getParser().parser.regexp.source})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
))
|
||||
.map(([_0, x, y, z]) => new this({
|
||||
X: Number(x),
|
||||
Y: Number(y),
|
||||
Z: Number(z),
|
||||
})),
|
||||
VectorEntity.grammar
|
||||
)
|
||||
}
|
||||
|
||||
22
js/entity/StringEntity.js
Executable file
22
js/entity/StringEntity.js
Executable file
@@ -0,0 +1,22 @@
|
||||
import P from "parsernostrum"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Utility from "../Utility.js"
|
||||
|
||||
export default class StringEntity extends IEntity {
|
||||
|
||||
static grammar = P.doubleQuotedString.map(insideString => Utility.unescapeString(insideString))
|
||||
|
||||
/** @param {String} value */
|
||||
constructor(value = "") {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value.toString()
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,14 @@
|
||||
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: AttributeInfo.createValue(""),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
static grammar = Grammar.symbol.map(v => new this(v))
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.symbol.map(v => new this(v))
|
||||
}
|
||||
|
||||
/** @param {String | Object} values */
|
||||
constructor(values) {
|
||||
if (values.constructor !== Object) {
|
||||
values = {
|
||||
value: values,
|
||||
}
|
||||
}
|
||||
super(values)
|
||||
/** @type {String} */ this.value
|
||||
/** @param {String} value */
|
||||
constructor(value = "") {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import BooleanEntity from "./BooleanEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
|
||||
export default class TerminalTypeEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
TerminalCategory: AttributeInfo.createType(String),
|
||||
TerminalSubCategory: AttributeInfo.createType(String),
|
||||
bTerminalIsConst: AttributeInfo.createType(Boolean),
|
||||
bTerminalIsWeakPointer: AttributeInfo.createType(Boolean),
|
||||
bTerminalIsUObjectWrapper: AttributeInfo.createType(Boolean),
|
||||
TerminalCategory: StringEntity,
|
||||
TerminalSubCategory: StringEntity,
|
||||
bTerminalIsConst: BooleanEntity,
|
||||
bTerminalIsWeakPointer: BooleanEntity,
|
||||
bTerminalIsUObjectWrapper: BooleanEntity,
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/** @template {any[]} T */
|
||||
export default class Union {
|
||||
|
||||
/** @type {T} */
|
||||
#values
|
||||
get values() {
|
||||
return this.#values
|
||||
}
|
||||
|
||||
/** @param {T} values */
|
||||
constructor(...values) {
|
||||
this.#values = values
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,32 @@
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import P 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 grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
// Lookbehind
|
||||
Parsernostrum.reg(
|
||||
new RegExp(`(${Grammar.Regex.Path.source}|${Grammar.Regex.Symbol.source}\\s*)?\\(\\s*`),
|
||||
1
|
||||
),
|
||||
Parsernostrum.seq(Grammar.attributeName, Grammar.equalSeparation).map(([attribute, equal]) => attribute)
|
||||
.chain(attributeName =>
|
||||
Grammar.unknownValue.map(attributeValue =>
|
||||
values => values[attributeName] = attributeValue
|
||||
)
|
||||
static grammar = P.seq(
|
||||
// Lookbehind
|
||||
P.reg(new RegExp(`(${Grammar.Regex.Path.source}|${Grammar.Regex.Symbol.source}\\s*)?\\(\\s*`), 1),
|
||||
P.seq(Grammar.attributeName, Grammar.equalSeparation).map(([attribute, equal]) => attribute)
|
||||
.chain(attributeName =>
|
||||
Grammar.unknownValue.map(attributeValue =>
|
||||
values => values[attributeName] = attributeValue
|
||||
)
|
||||
.sepBy(Grammar.commaSeparation),
|
||||
Parsernostrum.reg(/\s*(?:,\s*)?\)/),
|
||||
).map(([lookbehind, attributes, _2]) => {
|
||||
lookbehind ??= ""
|
||||
let values = {}
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
return new this(values)
|
||||
})
|
||||
}
|
||||
)
|
||||
.sepBy(Grammar.commaSeparation),
|
||||
P.reg(/\s*(?:,\s*)?\)/),
|
||||
).map(([lookbehind, attributes, _2]) => {
|
||||
lookbehind ??= ""
|
||||
let values = {}
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
return new this(values)
|
||||
})
|
||||
|
||||
constructor(values) {
|
||||
super(values, true)
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,20 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import PinEntity from "./PinEntity.js"
|
||||
|
||||
export default class UnknownPinEntity extends PinEntity {
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(
|
||||
new RegExp(`(${Grammar.Regex.Symbol.source})\\s*\\(\\s*`),
|
||||
1
|
||||
),
|
||||
Grammar.createAttributeGrammar(this).sepBy(Grammar.commaSeparation),
|
||||
Parsernostrum.reg(/\s*(?:,\s*)?\)/)
|
||||
).map(([lookbehind, attributes, _2]) => {
|
||||
lookbehind ??= ""
|
||||
let values = {}
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
return new this(values)
|
||||
})
|
||||
}
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values, true)
|
||||
}
|
||||
static grammar = P.seq(
|
||||
P.reg(new RegExp(`(${Grammar.Regex.Symbol.source})\\s*\\(\\s*`), 1),
|
||||
Grammar.createAttributeGrammar(this).sepBy(Grammar.commaSeparation),
|
||||
P.reg(/\s*(?:,\s*)?\)/)
|
||||
).map(([lookbehind, attributes, _2]) => {
|
||||
lookbehind ??= ""
|
||||
let values = {}
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
return new this(values)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import BooleanEntity from "./BooleanEntity.js"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
|
||||
export default class VariableReferenceEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
MemberScope: AttributeInfo.createType(String),
|
||||
MemberName: AttributeInfo.createValue(""),
|
||||
MemberGuid: AttributeInfo.createType(GuidEntity),
|
||||
bSelfContext: AttributeInfo.createType(Boolean),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this)
|
||||
MemberScope: StringEntity,
|
||||
MemberName: StringEntity.withDefault(),
|
||||
MemberGuid: GuidEntity,
|
||||
bSelfContext: BooleanEntity,
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
|
||||
@@ -1,34 +1,24 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import NumberEntity from "./NumberEntity.js"
|
||||
|
||||
export default class Vector2DEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
X: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
Y: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this, false)
|
||||
X: NumberEntity.withDefault(),
|
||||
Y: NumberEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this, false)
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {Number} */ this.X
|
||||
/** @type {Number} */ this.Y
|
||||
/** @type {NumberEntity} */ this.X
|
||||
/** @type {NumberEntity} */ this.Y
|
||||
}
|
||||
|
||||
/** @returns {[Number, Number]} */
|
||||
toArray() {
|
||||
return [this.X, this.Y]
|
||||
return [this.X.valueOf(), this.Y.valueOf()]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,28 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import NumberEntity from "./NumberEntity.js"
|
||||
|
||||
export default class Vector4DEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
X: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
Y: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
Z: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
W: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(Vector4DEntity, false)
|
||||
X: NumberEntity.withDefault(),
|
||||
Y: NumberEntity.withDefault(),
|
||||
Z: NumberEntity.withDefault(),
|
||||
W: NumberEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(Vector4DEntity, false)
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {Number} */ this.X
|
||||
/** @type {Number} */ this.Y
|
||||
/** @type {Number} */ this.Z
|
||||
/** @type {Number} */ this.W
|
||||
/** @type {NumberEntity} */ this.X
|
||||
/** @type {NumberEntity} */ this.Y
|
||||
/** @type {NumberEntity} */ this.Z
|
||||
/** @type {NumberEntity} */ this.W
|
||||
}
|
||||
|
||||
/** @returns {[Number, Number, Number, Number]} */
|
||||
toArray() {
|
||||
return [this.X, this.Y, this.Z, this.W]
|
||||
return [this.X.valueOf(), this.Y.valueOf(), this.Z.valueOf(), this.W.valueOf()]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,26 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import AttributeInfo from "./AttributeInfo.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import NumberEntity from "./NumberEntity.js"
|
||||
|
||||
export default class VectorEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
X: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
Y: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
Z: new AttributeInfo({
|
||||
default: 0,
|
||||
expected: true,
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(VectorEntity, false)
|
||||
X: NumberEntity.withDefault(),
|
||||
Y: NumberEntity.withDefault(),
|
||||
Z: NumberEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(VectorEntity, false)
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {Number} */ this.X
|
||||
/** @type {Number} */ this.Y
|
||||
/** @type {Number} */ this.Z
|
||||
/** @type {NumberEntity} */ this.X
|
||||
/** @type {NumberEntity} */ this.Y
|
||||
/** @type {NumberEntity} */ this.Z
|
||||
}
|
||||
|
||||
/** @returns {[Number, Number, Number]} */
|
||||
toArray() {
|
||||
return [this.X, this.Y, this.Z]
|
||||
return [this.X.valueOf(), this.Y.valueOf(), this.Z.valueOf()]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,20 +14,18 @@ export default class KnotEntity extends ObjectEntity {
|
||||
values.Name = "K2Node_Knot"
|
||||
const inputPinEntity = new PinEntity(
|
||||
{ PinName: "InputPin" },
|
||||
true
|
||||
)
|
||||
const outputPinEntity = new PinEntity(
|
||||
{
|
||||
PinName: "OutputPin",
|
||||
Direction: "EGPD_Output",
|
||||
},
|
||||
true
|
||||
)
|
||||
if (pinReferenceForType) {
|
||||
inputPinEntity.copyTypeFrom(pinReferenceForType)
|
||||
outputPinEntity.copyTypeFrom(pinReferenceForType)
|
||||
}
|
||||
values["CustomProperties"] = [inputPinEntity, outputPinEntity]
|
||||
super(values, true)
|
||||
super(values)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user