RBSerialization 2D Vector

This commit is contained in:
barsdeveloper
2023-09-26 22:12:39 +02:00
parent 71e7c12675
commit 42b6aefeed
9 changed files with 174 additions and 53 deletions

View File

@@ -2,7 +2,11 @@
import Configuration from "../../js/Configuration.js"
import generateNodeTests from "../fixtures/testUtilities.js"
import IntegerEntity from "../../js/entity/IntegerEntity.js"
import LinearColorEntity from "../../js/entity/LinearColorEntity.js"
import NodeElement from "../../js/element/NodeElement.js"
import PinElement from "../../js/element/PinElement.js"
import RBSerializationVector2DEntity from "../../js/entity/RBSerializationVector2DEntity.js"
import Utility from "../../js/Utility.js"
import VectorEntity from "../../js/entity/VectorEntity.js"
@@ -415,6 +419,48 @@ const tests = [
expect(Utility.approximatelyEqual(constantPin.getDefaultValue().A, a)).to.be.true
}
},
{
name: "Temporal Sobol",
value: String.raw`
Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name="MaterialGraphNode_9" ExportPath=/Script/UnrealEd.MaterialGraphNode'"/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_9"'
Begin Object Class=/Script/Engine.MaterialExpressionTemporalSobol Name="MaterialExpressionTemporalSobol_0" ExportPath=/Script/Engine.MaterialExpressionTemporalSobol'"/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_9.MaterialExpressionTemporalSobol_0"'
End Object
Begin Object Name="MaterialExpressionTemporalSobol_0" ExportPath=/Script/Engine.MaterialExpressionTemporalSobol'"/Engine/Transient.NewMaterial:MaterialGraph_0.MaterialGraphNode_9.MaterialExpressionTemporalSobol_0"'
"ConstIndex"=4
"ConstSeed"=(X=77.000000,Y=55.000000)
"MaterialExpressionEditorX"=-345
"MaterialExpressionEditorY"=225
"MaterialExpressionGuid"=D1A3B12340EE27538A3109B7B3D0E119
"Material"=/Script/UnrealEd.PreviewMaterial'"/Engine/Transient.NewMaterial"'
End Object
"MaterialExpression"=/Script/Engine.MaterialExpressionTemporalSobol'"MaterialExpressionTemporalSobol_0"'
"NodePosX"=-345
"NodePosY"=225
"NodeGuid"=5BE5108B48EB26B6366D4DA6AF99285D
CustomProperties Pin (PinId=E9B08066434FD243EF8856B11A08588D,PinName="Index",PinType.PinCategory="optional",PinType.PinSubCategory="int",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="4",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=4EB376FB4105AA0CFA52D990C82FE284,PinName="Seed",PinType.PinCategory="optional",PinType.PinSubCategory="rg",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="X=77.000 Y=55.000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=4A57DE0448EEA04661E83AA561BE2D94,PinName="Output",PinFriendlyName=NSLOCTEXT("MaterialGraphNode", "Space", " "),Direction="EGPD_Output",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
`,
color: Configuration.nodeColors.green,
icon: false,
pins: 3,
pinNames: [
"Index",
"Seed"
],
delegate: false,
development: false,
additionalTest:
/** @param {NodeElement} node */
node => {
const indexPin = /** @type {PinElement<IntegerEntity>} */(node.querySelectorAll("ueb-pin")[0])
const seedPin = /** @type {PinElement<RBSerializationVector2DEntity>} */(node.querySelectorAll("ueb-pin")[1])
expect(indexPin.getDefaultValue().value).to.be.equal(4)
expect(seedPin.getDefaultValue().X).to.be.equal(77)
expect(seedPin.getDefaultValue().Y).to.be.equal(55)
}
},
]
generateNodeTests(tests)

113
dist/ueblueprint.js vendored
View File

@@ -83,12 +83,12 @@ class Configuration {
// End of upper case work (upper case followed by either word or number)
+ "|(?<=[A-Z])"
+ /* Except "UVs" */ "(?<!U(?=Vs(?![a-z])))"
+ /* Except V3 */ "(?<!V(?=3(?![0-9])))"
+ /* Except V2, V3 */ "(?<!V(?=[23](?![0-9])))"
+ /* Except T2d */ "(?<!T(?=2d(?![a-z])))"
+ "(?=[A-Z][a-z]|[0-9])"
// Number followed by a letter
+ "|(?<=[0-9])"
+ /* Except 2D 3D */ "(?<![23](?=[dD](?![a-z])))"
+ /* Except 2D, 3D */ "(?<![23](?=[dD](?![a-z])))"
+ "(?=[a-zA-Z])"
// "Alpha__Bravo" => "Alpha Bravo"
+ "|\\s*_+\\s*"
@@ -1439,6 +1439,7 @@ class Grammar {
)
static guid = P.regex(new RegExp(`${Grammar.Regex.HexDigit.source}{32}`))
static commaSeparation = P.regex(/\s*,\s*(?!\))/)
static commaOrSpaceSeparation = P.regex(/\s*,\s*(?!\))|\s+/)
static equalSeparation = P.regex(/\s*=\s*/)
static typeReference = P.alt(P.regex(Grammar.Regex.Path), this.symbol)
static hexColorChannel = P.regex(new RegExp(Grammar.Regex.HexDigit.source + "{2}"))
@@ -1590,7 +1591,7 @@ class Grammar {
* @param {Boolean | Number} acceptUnknownKeys Number to specify the limit or true, to let it be a reasonable value
* @returns {Parsimmon.Parser<T>}
*/
static createEntityGrammar = (entityType, acceptUnknownKeys = true) =>
static createEntityGrammar = (entityType, acceptUnknownKeys = true, entriesSeparator = this.commaSeparation) =>
P.seq(
this.regexMap(
entityType.lookbehind instanceof Union
@@ -1600,7 +1601,7 @@ class Grammar {
: /()\(\s*/,
result => result[1]
),
this.createAttributeGrammar(entityType).sepBy1(this.commaSeparation),
this.createAttributeGrammar(entityType).sepBy1(entriesSeparator),
P.regex(/\s*(?:,\s*)?\)/), // trailing comma
)
.map(([lookbehind, attributes, _2]) => {
@@ -2700,6 +2701,54 @@ class PinTypeEntity extends IEntity {
}
}
class Vector2DEntity extends IEntity {
static attributes = {
...super.attributes,
X: {
default: 0,
expected: true,
},
Y: {
default: 0,
expected: true,
},
}
static {
this.cleanupAttributes(this.attributes);
}
static grammar = this.createGrammar()
static createGrammar() {
return Grammar.createEntityGrammar(this, false)
}
constructor(values) {
super(values);
/** @type {Number} */ this.X;
/** @type {Number} */ this.Y;
}
}
class RBSerializationVector2DEntity extends Vector2DEntity {
static grammar = this.createGrammar()
static createGrammar() {
return Parsimmon.alt(
Parsimmon.seq(
Parsimmon.string("X").then(Grammar.equalSeparation).then(Grammar.number),
Parsimmon.regex(Grammar.Regex.InlineWhitespace),
Parsimmon.string("Y").then(Grammar.equalSeparation).then(Grammar.number),
).map(([x, _1, y]) => new this({
X: x,
Y: y,
})),
Vector2DEntity.createGrammar()
)
}
}
class RotatorEntity extends IEntity {
static attributes = {
@@ -2770,35 +2819,6 @@ class SimpleSerializationRotatorEntity extends RotatorEntity {
}
}
class Vector2DEntity extends IEntity {
static attributes = {
...super.attributes,
X: {
default: 0,
expected: true,
},
Y: {
default: 0,
expected: true,
},
}
static {
this.cleanupAttributes(this.attributes);
}
static grammar = this.createGrammar()
static createGrammar() {
return Grammar.createEntityGrammar(this, false)
}
constructor(values) {
super(values);
/** @type {Number} */ this.X;
/** @type {Number} */ this.Y;
}
}
class SimpleSerializationVector2DEntity extends Vector2DEntity {
static grammar = this.createGrammar()
@@ -2894,6 +2914,7 @@ class PinEntity extends IEntity {
}
static #alternativeTypeEntityMap = {
"enum": EnumDisplayValueEntity,
"rg": RBSerializationVector2DEntity,
[Configuration.paths.rotator]: SimpleSerializationRotatorEntity,
[Configuration.paths.vector]: SimpleSerializationVectorEntity,
[Configuration.paths.vector2D]: SimpleSerializationVector2DEntity,
@@ -3016,12 +3037,17 @@ class PinEntity extends IEntity {
return this.PinType.PinSubCategoryObject.path
}
if (category === "optional") {
if (this.PinType.PinSubCategory === "red") {
return "real"
} else if (this.PinType.PinSubCategory === "rgb") {
return Configuration.paths.vector
} else if (this.PinType.PinSubCategory === "rgba") {
return Configuration.paths.linearColor
switch (this.PinType.PinSubCategory) {
case "int":
return "int"
case "red":
return "real"
case "rg":
return "rg"
case "rgb":
return Configuration.paths.vector
case "rgba":
return Configuration.paths.linearColor
}
}
if (this.isEnum()) {
@@ -10837,6 +10863,7 @@ class PinElement extends IElement {
"int64": Int64PinTemplate,
"MUTABLE_REFERENCE": ReferencePinTemplate,
"name": NamePinTemplate,
"rg": VectorInputPinTemplate,
"real": RealPinTemplate,
"string": StringPinTemplate,
[Configuration.paths.linearColor]: LinearColorPinTemplate,
@@ -11815,6 +11842,14 @@ function initializeSerializerFactory() {
new Serializer(TerminalTypeEntity, Serializer.bracketsWrapped)
);
SerializerFactory.registerSerializer(
RBSerializationVector2DEntity,
new CustomSerializer(
(value, insideString) => `X=${value.X} Y=${value.Y}`,
RBSerializationVector2DEntity
)
);
SerializerFactory.registerSerializer(
RotatorEntity,
new Serializer(RotatorEntity, Serializer.bracketsWrapped)

File diff suppressed because one or more lines are too long

View File

@@ -59,12 +59,12 @@ export default class Configuration {
// End of upper case work (upper case followed by either word or number)
+ "|(?<=[A-Z])"
+ /* Except "UVs" */ "(?<!U(?=Vs(?![a-z])))"
+ /* Except V3 */ "(?<!V(?=3(?![0-9])))"
+ /* Except V2, V3 */ "(?<!V(?=[23](?![0-9])))"
+ /* Except T2d */ "(?<!T(?=2d(?![a-z])))"
+ "(?=[A-Z][a-z]|[0-9])"
// Number followed by a letter
+ "|(?<=[0-9])"
+ /* Except 2D 3D */ "(?<![23](?=[dD](?![a-z])))"
+ /* Except 2D, 3D */ "(?<![23](?=[dD](?![a-z])))"
+ "(?=[a-zA-Z])"
// "Alpha__Bravo" => "Alpha Bravo"
+ "|\\s*_+\\s*"

View File

@@ -35,6 +35,7 @@ export default class PinElement extends IElement {
"int64": Int64PinTemplate,
"MUTABLE_REFERENCE": ReferencePinTemplate,
"name": NamePinTemplate,
"rg": Vector2DPinTemplate,
"real": RealPinTemplate,
"string": StringPinTemplate,
[Configuration.paths.linearColor]: LinearColorPinTemplate,

View File

@@ -14,6 +14,7 @@ import LocalizedTextEntity from "./LocalizedTextEntity.js"
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
import PinReferenceEntity from "./PinReferenceEntity.js"
import PinTypeEntity from "./PinTypeEntity.js"
import RBSerializationVector2DEntity from "./RBSerializationVector2DEntity.js"
import RotatorEntity from "./RotatorEntity.js"
import SimpleSerializationRotatorEntity from "./SimpleSerializationRotatorEntity.js"
import SimpleSerializationVector2DEntity from "./SimpleSerializationVector2DEntity.js"
@@ -43,6 +44,7 @@ export default class PinEntity extends IEntity {
}
static #alternativeTypeEntityMap = {
"enum": EnumDisplayValueEntity,
"rg": RBSerializationVector2DEntity,
[Configuration.paths.rotator]: SimpleSerializationRotatorEntity,
[Configuration.paths.vector]: SimpleSerializationVectorEntity,
[Configuration.paths.vector2D]: SimpleSerializationVector2DEntity,
@@ -165,12 +167,17 @@ export default class PinEntity extends IEntity {
return this.PinType.PinSubCategoryObject.path
}
if (category === "optional") {
if (this.PinType.PinSubCategory === "red") {
return "real"
} else if (this.PinType.PinSubCategory === "rgb") {
return Configuration.paths.vector
} else if (this.PinType.PinSubCategory === "rgba") {
return Configuration.paths.linearColor
switch (this.PinType.PinSubCategory) {
case "int":
return "int"
case "red":
return "real"
case "rg":
return "rg"
case "rgb":
return Configuration.paths.vector
case "rgba":
return Configuration.paths.linearColor
}
}
if (this.isEnum()) {

View File

@@ -0,0 +1,22 @@
import Grammar from "../serialization/Grammar.js"
import Parsimmon from "parsimmon"
import Vector2DEntity from "./Vector2DEntity.js"
export default class RBSerializationVector2DEntity extends Vector2DEntity {
static grammar = this.createGrammar()
static createGrammar() {
return Parsimmon.alt(
Parsimmon.seq(
Parsimmon.string("X").then(Grammar.equalSeparation).then(Grammar.number),
Parsimmon.regex(Grammar.Regex.InlineWhitespace),
Parsimmon.string("Y").then(Grammar.equalSeparation).then(Grammar.number),
).map(([x, _1, y]) => new this({
X: x,
Y: y,
})),
Vector2DEntity.createGrammar()
)
}
}

View File

@@ -98,6 +98,7 @@ export default class Grammar {
)
static guid = P.regex(new RegExp(`${Grammar.Regex.HexDigit.source}{32}`))
static commaSeparation = P.regex(/\s*,\s*(?!\))/)
static commaOrSpaceSeparation = P.regex(/\s*,\s*(?!\))|\s+/)
static equalSeparation = P.regex(/\s*=\s*/)
static typeReference = P.alt(P.regex(Grammar.Regex.Path), this.symbol)
static hexColorChannel = P.regex(new RegExp(Grammar.Regex.HexDigit.source + "{2}"))
@@ -249,7 +250,7 @@ export default class Grammar {
* @param {Boolean | Number} acceptUnknownKeys Number to specify the limit or true, to let it be a reasonable value
* @returns {Parsimmon.Parser<T>}
*/
static createEntityGrammar = (entityType, acceptUnknownKeys = true) =>
static createEntityGrammar = (entityType, acceptUnknownKeys = true, entriesSeparator = this.commaSeparation) =>
P.seq(
this.regexMap(
entityType.lookbehind instanceof Union
@@ -259,7 +260,7 @@ export default class Grammar {
: /()\(\s*/,
result => result[1]
),
this.createAttributeGrammar(entityType).sepBy1(this.commaSeparation),
this.createAttributeGrammar(entityType).sepBy1(entriesSeparator),
P.regex(/\s*(?:,\s*)?\)/), // trailing comma
)
.map(([lookbehind, attributes, _2]) => {

View File

@@ -23,6 +23,7 @@ import Parsimmon from "parsimmon"
import PathSymbolEntity from "../entity/PathSymbolEntity.js"
import PinEntity from "../entity/PinEntity.js"
import PinReferenceEntity from "../entity/PinReferenceEntity.js"
import RBSerializationVector2DEntity from "../entity/RBSerializationVector2DEntity.js"
import RotatorEntity from "../entity/RotatorEntity.js"
import Serializer from "./Serializer.js"
import SerializerFactory from "./SerializerFactory.js"
@@ -241,6 +242,14 @@ export default function initializeSerializerFactory() {
new Serializer(TerminalTypeEntity, Serializer.bracketsWrapped)
)
SerializerFactory.registerSerializer(
RBSerializationVector2DEntity,
new CustomSerializer(
(value, insideString) => `X=${value.X} Y=${value.Y}`,
RBSerializationVector2DEntity
)
)
SerializerFactory.registerSerializer(
RotatorEntity,
new Serializer(RotatorEntity, Serializer.bracketsWrapped)