InvariantTextEntity, unexpected properties fixes

This commit is contained in:
barsdeveloper
2022-04-18 00:11:31 +02:00
parent 488f8eda5f
commit d43ae1b11f
6 changed files with 113 additions and 54 deletions

82
dist/ueblueprint.js vendored
View File

@@ -398,27 +398,20 @@ class IEntity {
static attributes = {}
constructor(values) {
// @ts-expect-error
const attributes = this.constructor.attributes;
if (values.constructor !== Object && Object.getOwnPropertyNames(attributes).length == 1) {
// Where there is just one attribute, option can be the value of that attribute
values = {
[Object.getOwnPropertyNames(attributes)[0]]: values
};
}
/**
* @param {String[]} prefix
* @param {Object} target
* @param {Object} properties
* @param {Object} values
* @param {String} prefix
*/
const defineAllAttributes = (prefix, target, properties, values) => {
let fullKey = prefix.concat("");
const last = fullKey.length - 1;
const defineAllAttributes = (target, properties, values, prefix = "") => {
for (let property of Utility.mergeArrays(
Object.getOwnPropertyNames(properties),
Object.getOwnPropertyNames(values ?? {})
)) {
fullKey[last] = property;
if (!(property in properties)) {
console.warn(`Property ${prefix}${property} is not defined in ${this.constructor.name}`);
}
let defaultValue = properties[property];
const defaultType = (defaultValue instanceof TypeInitialization)
? defaultValue.type
@@ -428,7 +421,7 @@ class IEntity {
// Not instanceof because all objects are instenceof Object, exact match needed
if (defaultType === Object) {
target[property] = {};
defineAllAttributes(fullKey, target[property], properties[property], values[property]);
defineAllAttributes(target[property], properties[property], values[property], property + ".");
continue
}
/*
@@ -438,7 +431,7 @@ class IEntity {
* - A type: the default value will be default constructed object without arguments.
* - A proper value.
*/
const value = Utility.objectGet(values, fullKey);
const value = Utility.objectGet(values, [property]);
if (value !== undefined) {
target[property] = TypeInitialization.sanitize(value, defaultType);
continue
@@ -460,7 +453,15 @@ class IEntity {
target[property] = TypeInitialization.sanitize(defaultValue, defaultType);
}
};
defineAllAttributes([], this, attributes, values);
// @ts-expect-error
const attributes = this.constructor.attributes;
if (values.constructor !== Object && Object.getOwnPropertyNames(attributes).length == 1) {
// Where there is just one attribute, option can be the value of that attribute
values = {
[Object.getOwnPropertyNames(attributes)[0]]: values
};
}
defineAllAttributes(this, attributes, values);
}
}
@@ -579,6 +580,21 @@ class IntegerEntity extends IEntity {
// @ts-check
class InvariantTextEntity extends IEntity {
static lookbehind = "INVTEXT"
static attributes = {
value: String,
}
constructor(options = {}) {
super(options);
/** @type {String} */ this.value;
}
}
// @ts-check
class KeyBindingEntity extends IEntity {
static attributes = {
@@ -918,6 +934,8 @@ class Grammar {
return r.Reference
case LocalizedTextEntity:
return r.LocalizedText
case InvariantTextEntity:
return r.InvariantText
case PinReferenceEntity:
return r.PinReference
case FunctionReferenceEntity:
@@ -959,7 +977,7 @@ class Grammar {
/**
* @template T
* @param {new () => T} entityType
* @param {new (values: Object) => T} entityType
* @returns {Parsimmon.Parser<T>}
*/
static createMultiAttributeGrammar = (r, entityType) =>
@@ -979,9 +997,9 @@ class Grammar {
.skip(P.regex(/,?/).then(P.optWhitespace)), // Optional trailing comma
P.string(')'),
(_, attributes, __) => {
let result = new entityType();
attributes.forEach(attributeSetter => attributeSetter(result));
return result
let values = {};
attributes.forEach(attributeSetter => attributeSetter(values));
return new entityType(values)
}
)
@@ -1066,6 +1084,12 @@ class Grammar {
})
)
InvariantText = r => r.String.trim(P.optWhitespace).wrap(
P.string(InvariantTextEntity.lookbehind).skip(P.optWhitespace).skip(P.string("(")),
P.string(")")
)
.map(value => new InvariantTextEntity({ value: value }))
AttributeAnyValue = r => P.alt(
r.Null,
r.None,
@@ -1074,8 +1098,9 @@ class Grammar {
r.Integer,
r.String,
r.Guid,
r.Reference,
r.LocalizedText
r.LocalizedText,
r.InvariantText,
r.Reference
)
PinReference = r => P.seqMap(
@@ -3087,11 +3112,9 @@ class SelectableDraggableTemplate extends ITemplate {
createInputObjects(element) {
return [
...super.createInputObjects(element),
...[
new MouseMoveNodes(element, element.blueprint, {
looseTarget: true
}),
]
new MouseMoveNodes(element, element.blueprint, {
looseTarget: true
}),
]
}
@@ -4504,6 +4527,11 @@ function initializeSerializerFactory() {
new GeneralSerializer(v => `${LocalizedTextEntity.lookbehind}(${v})`, LocalizedTextEntity, "", ", ", false, "", _ => "")
);
SerializerFactory.registerSerializer(
InvariantTextEntity,
new GeneralSerializer(v => `${InvariantTextEntity.lookbehind}(${v})`, InvariantTextEntity, "", ", ", false, "", _ => "")
);
SerializerFactory.registerSerializer(
PinReferenceEntity,
new GeneralSerializer(v => v, PinReferenceEntity, "", " ", false, "", _ => "")

View File

@@ -8,27 +8,20 @@ export default class IEntity {
static attributes = {}
constructor(values) {
// @ts-expect-error
const attributes = this.constructor.attributes
if (values.constructor !== Object && Object.getOwnPropertyNames(attributes).length == 1) {
// Where there is just one attribute, option can be the value of that attribute
values = {
[Object.getOwnPropertyNames(attributes)[0]]: values
}
}
/**
* @param {String[]} prefix
* @param {Object} target
* @param {Object} properties
* @param {Object} values
* @param {String} prefix
*/
const defineAllAttributes = (prefix, target, properties, values) => {
let fullKey = prefix.concat("")
const last = fullKey.length - 1
const defineAllAttributes = (target, properties, values, prefix = "") => {
for (let property of Utility.mergeArrays(
Object.getOwnPropertyNames(properties),
Object.getOwnPropertyNames(values ?? {})
)) {
fullKey[last] = property
if (!(property in properties)) {
console.warn(`Property ${prefix}${property} is not defined in ${this.constructor.name}`)
}
let defaultValue = properties[property]
const defaultType = (defaultValue instanceof TypeInitialization)
? defaultValue.type
@@ -38,7 +31,7 @@ export default class IEntity {
// Not instanceof because all objects are instenceof Object, exact match needed
if (defaultType === Object) {
target[property] = {}
defineAllAttributes(fullKey, target[property], properties[property], values[property])
defineAllAttributes(target[property], properties[property], values[property], property + ".")
continue
}
/*
@@ -48,7 +41,7 @@ export default class IEntity {
* - A type: the default value will be default constructed object without arguments.
* - A proper value.
*/
const value = Utility.objectGet(values, fullKey)
const value = Utility.objectGet(values, [property])
if (value !== undefined) {
target[property] = TypeInitialization.sanitize(value, defaultType)
continue
@@ -70,6 +63,14 @@ export default class IEntity {
target[property] = TypeInitialization.sanitize(defaultValue, defaultType)
}
}
defineAllAttributes([], this, attributes, values)
// @ts-expect-error
const attributes = this.constructor.attributes
if (values.constructor !== Object && Object.getOwnPropertyNames(attributes).length == 1) {
// Where there is just one attribute, option can be the value of that attribute
values = {
[Object.getOwnPropertyNames(attributes)[0]]: values
}
}
defineAllAttributes(this, attributes, values)
}
}

View File

@@ -0,0 +1,16 @@
// @ts-check
import IEntity from "./IEntity"
export default class InvariantTextEntity extends IEntity {
static lookbehind = "INVTEXT"
static attributes = {
value: String,
}
constructor(options = {}) {
super(options)
/** @type {String} */ this.value
}
}

View File

@@ -4,6 +4,7 @@ import FunctionReferenceEntity from "../entity/FunctionReferenceEntity"
import GuidEntity from "../entity/GuidEntity"
import IdentifierEntity from "../entity/IdentifierEntity"
import IntegerEntity from "../entity/IntegerEntity"
import InvariantTextEntity from "../entity/InvariantTextEntity"
import KeyBindingEntity from "../entity/KeyBindingEntity"
import LocalizedTextEntity from "../entity/LocalizedTextEntity"
import ObjectEntity from "../entity/ObjectEntity"
@@ -38,6 +39,8 @@ export default class Grammar {
return r.Reference
case LocalizedTextEntity:
return r.LocalizedText
case InvariantTextEntity:
return r.InvariantText
case PinReferenceEntity:
return r.PinReference
case FunctionReferenceEntity:
@@ -79,7 +82,7 @@ export default class Grammar {
/**
* @template T
* @param {new () => T} entityType
* @param {new (values: Object) => T} entityType
* @returns {Parsimmon.Parser<T>}
*/
static createMultiAttributeGrammar = (r, entityType) =>
@@ -99,9 +102,9 @@ export default class Grammar {
.skip(P.regex(/,?/).then(P.optWhitespace)), // Optional trailing comma
P.string(')'),
(_, attributes, __) => {
let result = new entityType()
attributes.forEach(attributeSetter => attributeSetter(result))
return result
let values = {}
attributes.forEach(attributeSetter => attributeSetter(values))
return new entityType(values)
}
)
@@ -186,6 +189,12 @@ export default class Grammar {
})
)
InvariantText = r => r.String.trim(P.optWhitespace).wrap(
P.string(InvariantTextEntity.lookbehind).skip(P.optWhitespace).skip(P.string("(")),
P.string(")")
)
.map(value => new InvariantTextEntity({ value: value }))
AttributeAnyValue = r => P.alt(
r.Null,
r.None,
@@ -194,8 +203,9 @@ export default class Grammar {
r.Integer,
r.String,
r.Guid,
r.Reference,
r.LocalizedText
r.LocalizedText,
r.InvariantText,
r.Reference
)
PinReference = r => P.seqMap(

View File

@@ -16,6 +16,7 @@ import PinEntity from "../entity/PinEntity"
import PinReferenceEntity from "../entity/PinReferenceEntity"
import SerializerFactory from "./SerializerFactory"
import ToStringSerializer from "./ToStringSerializer"
import InvariantTextEntity from "../entity/InvariantTextEntity"
export default function initializeSerializerFactory() {
@@ -44,6 +45,11 @@ export default function initializeSerializerFactory() {
new GeneralSerializer(v => `${LocalizedTextEntity.lookbehind}(${v})`, LocalizedTextEntity, "", ", ", false, "", _ => "")
)
SerializerFactory.registerSerializer(
InvariantTextEntity,
new GeneralSerializer(v => `${InvariantTextEntity.lookbehind}(${v})`, InvariantTextEntity, "", ", ", false, "", _ => "")
)
SerializerFactory.registerSerializer(
PinReferenceEntity,
new GeneralSerializer(v => v, PinReferenceEntity, "", " ", false, "", _ => "")

View File

@@ -19,11 +19,9 @@ export default class SelectableDraggableTemplate extends ITemplate {
createInputObjects(element) {
return [
...super.createInputObjects(element),
...[
new MouseMoveNodes(element, element.blueprint, {
looseTarget: true
}),
]
new MouseMoveNodes(element, element.blueprint, {
looseTarget: true
}),
]
}