mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-15 09:44:49 +08:00
Several serialization and deserialization fixes
This commit is contained in:
@@ -26,7 +26,7 @@ describe("Entity initialization", () => {
|
||||
Entity2,
|
||||
new Serializer(
|
||||
Entity2,
|
||||
v => `{\n${v}\n}`,
|
||||
(entity, v) => `{\n${v}\n}`,
|
||||
"\n",
|
||||
false,
|
||||
": ",
|
||||
@@ -37,7 +37,7 @@ describe("Entity initialization", () => {
|
||||
Entity1,
|
||||
new Serializer(
|
||||
Entity1,
|
||||
v => `Entity1(${v})`,
|
||||
(entity, v) => `Entity1(${v})`,
|
||||
", ",
|
||||
false,
|
||||
"=",
|
||||
@@ -147,7 +147,7 @@ describe("Entity initialization", () => {
|
||||
Entity3,
|
||||
new Serializer(
|
||||
Entity3,
|
||||
v => `[[\n${v}\n]]`,
|
||||
(entity, v) => `[[\n${v}\n]]`,
|
||||
"\n",
|
||||
false,
|
||||
": ",
|
||||
@@ -158,7 +158,7 @@ describe("Entity initialization", () => {
|
||||
Entity1,
|
||||
new Serializer(
|
||||
Entity1,
|
||||
v => `Entity1(${v})`,
|
||||
(entity, v) => `Entity1(${v})`,
|
||||
", ",
|
||||
false,
|
||||
"=",
|
||||
@@ -287,7 +287,7 @@ describe("Entity initialization", () => {
|
||||
Entity4,
|
||||
new Serializer(
|
||||
Entity4,
|
||||
v => `Begin\n${v}\nEnd`,
|
||||
(entity, v) => `Begin\n${v}\nEnd`,
|
||||
"\n",
|
||||
false,
|
||||
" => ",
|
||||
|
||||
@@ -6,40 +6,72 @@ const tests = [
|
||||
{
|
||||
name: "ROS Change Element",
|
||||
value: String.raw`
|
||||
Begin Object Class=/Script/BlueprintGraph.K2Node_CustomEvent Name="K2Node_CustomEvent_13465"
|
||||
Begin Object Class=/Script/Engine.EdGraphPin_Deprecated Name="EdGraphPin_2859957"
|
||||
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_131095"
|
||||
NodePosX=-5024
|
||||
NodePosY=-1888
|
||||
NodeGuid=CC44F0434996CC21484572A242E1F72D
|
||||
Begin Object Class=EdGraphPin Name="EdGraphPin_3991113"
|
||||
End Object
|
||||
Begin Object Class=/Script/Engine.EdGraphPin_Deprecated Name="EdGraphPin_2859956"
|
||||
Begin Object Class=EdGraphPin Name="EdGraphPin_3991114"
|
||||
End Object
|
||||
Begin Object Class=/Script/Engine.EdGraphPin_Deprecated Name="EdGraphPin_2859955"
|
||||
Begin Object Class=EdGraphPin Name="EdGraphPin_3991115"
|
||||
End Object
|
||||
Begin Object Name="EdGraphPin_2859957"
|
||||
PinName="Element"
|
||||
Direction=EGPD_Output
|
||||
PinType=(PinCategory="int")
|
||||
LinkedTo(0)=None
|
||||
LinkedTo(1)=None
|
||||
Begin Object Class=EdGraphPin Name="EdGraphPin_3991116"
|
||||
End Object
|
||||
Begin Object Name="EdGraphPin_2859956"
|
||||
Begin Object Class=EdGraphPin Name="EdGraphPin_3991117"
|
||||
End Object
|
||||
Begin Object Class=EdGraphPin Name="EdGraphPin_3991118"
|
||||
End Object
|
||||
FunctionReference=(MemberParentClass=Class'/Script/ShooterGame.ShooterGameMode',MemberName="GetFloatOptionIni")
|
||||
Pins(0)=EdGraphPin'EdGraphPin_3991113'
|
||||
Pins(1)=EdGraphPin'EdGraphPin_3991114'
|
||||
Pins(2)=EdGraphPin'EdGraphPin_3991115'
|
||||
Pins(3)=EdGraphPin'EdGraphPin_3991116'
|
||||
Pins(4)=EdGraphPin'EdGraphPin_3991117'
|
||||
Pins(5)=EdGraphPin'EdGraphPin_3991118'
|
||||
ErrorType=1
|
||||
ErrorMsg="Error This blueprint (self) is not a ShooterGameMode, therefore \' Target \' must have a connection\nError This blueprint (self) is not a ShooterGameMode, therefore \' Target \' must have a connection"
|
||||
Begin Object Name="EdGraphPin_3991113"
|
||||
PinName="execute"
|
||||
PinType=(PinCategory="exec")
|
||||
LinkedTo(0)=EdGraphPin'"K2Node_CallFunction_113214.EdGraphPin_3991579"'
|
||||
End Object
|
||||
Begin Object Name="EdGraphPin_3991114"
|
||||
PinName="then"
|
||||
Direction=EGPD_Output
|
||||
PinType=(PinCategory="exec")
|
||||
LinkedTo(0)=None
|
||||
LinkedTo(0)=EdGraphPin'"K2Node_IfThenElse_7680.EdGraphPin_3991155"'
|
||||
End Object
|
||||
Begin Object Name="EdGraphPin_2859955"
|
||||
PinName="OutputDelegate"
|
||||
Begin Object Name="EdGraphPin_3991115"
|
||||
PinName="self"
|
||||
PinFriendlyName="Target"
|
||||
PinToolTip="Target\nShooter Game Mode Reference"
|
||||
PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/ShooterGame.ShooterGameMode')
|
||||
LinkedTo(0)=EdGraphPin'"K2Node_DynamicCast_2126.EdGraphPin_3990988"'
|
||||
End Object
|
||||
Begin Object Name="EdGraphPin_3991116"
|
||||
PinName="Section"
|
||||
PinToolTip="Section\nString"
|
||||
PinType=(PinCategory="string")
|
||||
DefaultValue="CrazysDinosStats"
|
||||
End Object
|
||||
Begin Object Name="EdGraphPin_3991117"
|
||||
PinName="OptionName"
|
||||
PinToolTip="Option Name\nString"
|
||||
PinType=(PinCategory="string")
|
||||
DefaultValue="DinoStamina"
|
||||
End Object
|
||||
Begin Object Name="EdGraphPin_3991118"
|
||||
PinName="ReturnValue"
|
||||
PinToolTip="Return Value\nFloat"
|
||||
Direction=EGPD_Output
|
||||
PinType=(PinCategory="delegate")
|
||||
PinType=(PinCategory="float")
|
||||
DefaultValue="0.0"
|
||||
AutogeneratedDefaultValue="0.0"
|
||||
LinkedTo(0)=EdGraphPin'"K2Node_CallFunction_131096.EdGraphPin_3991132"'
|
||||
LinkedTo(1)=EdGraphPin'"K2Node_CallFunction_131097.EdGraphPin_3991144"'
|
||||
LinkedTo(2)=EdGraphPin'"K2Node_VariableSet_21447.EdGraphPin_3992243"'
|
||||
End Object
|
||||
CustomFunctionName="ROS Change Element"
|
||||
FunctionFlags=2097344
|
||||
NodePosX=-3696
|
||||
NodePosY=-128
|
||||
ErrorType=1
|
||||
NodeGuid=A7AFBC3557734BFDA0D1E917569CA6A1
|
||||
CustomProperties Pin (PinId=989B6502AF0240A28DE51122C9F3F5D7,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=/Script/Engine.BlueprintGeneratedClass'"/Temp/Untitled_1.Untitled_1_C"',MemberName="ROS Change Element",MemberGuid=A7AFBC3557734BFDA0D1E917569CA6A1),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=385BD405C63F4EC5B7D55D902D37A6CE,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties UserDefinedPin ()
|
||||
End Object
|
||||
`,
|
||||
pins: 2,
|
||||
|
||||
@@ -92,7 +92,6 @@ describe("Serializer", () => {
|
||||
context("KeyBindingEntity", () => {
|
||||
let serializer = SerializerFactory.getSerializer(KeyBindingEntity)
|
||||
|
||||
|
||||
it("Parses A", () =>
|
||||
expect(serializer.read("A"))
|
||||
.to.be.instanceOf(KeyBindingEntity)
|
||||
@@ -115,6 +114,36 @@ describe("Serializer", () => {
|
||||
)
|
||||
})
|
||||
|
||||
context("ObjectReferenceEntity", () => {
|
||||
let serializer = SerializerFactory.getSerializer(ObjectReferenceEntity)
|
||||
|
||||
it("Parses Class", () =>
|
||||
expect(serializer.read("Class"))
|
||||
.to.be.instanceOf(ObjectReferenceEntity)
|
||||
.and.to.deep.contain({ type: "Class", path: "" })
|
||||
)
|
||||
it("Parses Class'/Script/ShooterGame.ShooterGameMode'", () =>
|
||||
expect(serializer.read(`Class'/Script/ShooterGame.ShooterGameMode'`))
|
||||
.to.be.instanceOf(ObjectReferenceEntity)
|
||||
.and.to.deep.contain({ type: "Class", path: "/Script/ShooterGame.ShooterGameMode" })
|
||||
)
|
||||
it(`Parses EdGraphPin'"K2Node_DynamicCast_2126.EdGraphPin_3990988"'`, () =>
|
||||
expect(serializer.read(`EdGraphPin'"K2Node_DynamicCast_2126.EdGraphPin_3990988"'`))
|
||||
.to.be.instanceOf(ObjectReferenceEntity)
|
||||
.and.to.deep.contain({ type: "EdGraphPin", path: "K2Node_DynamicCast_2126.EdGraphPin_3990988" })
|
||||
)
|
||||
it(`Parses /Script/Engine.EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:Do N"'`, () =>
|
||||
expect(serializer.read(`/Script/Engine.EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:Do N"'`))
|
||||
.to.be.instanceOf(ObjectReferenceEntity)
|
||||
.and.to.deep.contain({ type: "/Script/Engine.EdGraph", path: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:Do N" })
|
||||
)
|
||||
it(`Parses Function'"/Game/Mods/CrazyDinos/ElementalDragon/CDElementalDragon_Character_BP.SKEL_CDElementalDragon_Character_BP_C:ROS Change Element"'`, () =>
|
||||
expect(serializer.read(`Function'"/Game/Mods/CrazyDinos/ElementalDragon/CDElementalDragon_Character_BP.SKEL_CDElementalDragon_Character_BP_C:ROS Change Element"'`))
|
||||
.to.be.instanceOf(ObjectReferenceEntity)
|
||||
.and.to.deep.contain({ type: "Function", path: "/Game/Mods/CrazyDinos/ElementalDragon/CDElementalDragon_Character_BP.SKEL_CDElementalDragon_Character_BP_C:ROS Change Element" })
|
||||
)
|
||||
})
|
||||
|
||||
context("GuidEntity", () => {
|
||||
let serializer = SerializerFactory.getSerializer(GuidEntity)
|
||||
|
||||
@@ -308,11 +337,6 @@ describe("Serializer", () => {
|
||||
expect(parser.parse(`Class'"/Script/Engine.KismetSystemLibrary"'`).value.constructor)
|
||||
.equals(ObjectReferenceEntity)
|
||||
)
|
||||
it("Parses ObjectReferenceEntity 2", () =>
|
||||
expect(parser.parse(`Function'"/Game/Mods/CrazyDinos/ElementalDragon/CDElementalDragon_Character_BP.SKEL_CDElementalDragon_Character_BP_C:ROS Change Element"'`)
|
||||
.value.constructor)
|
||||
.equals(ObjectReferenceEntity)
|
||||
)
|
||||
it("Parses Numbers array", () =>
|
||||
expect(parser.parse("(1,2,3,4,5,6,7,8,9)").value).to.be.deep.equal([1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||
)
|
||||
|
||||
184
dist/ueblueprint.js
vendored
184
dist/ueblueprint.js
vendored
@@ -72,6 +72,7 @@ class Configuration {
|
||||
static gridSize = 16 // px
|
||||
static hexColorRegex = /^\s*#(?<r>[0-9a-fA-F]{2})(?<g>[0-9a-fA-F]{2})(?<b>[0-9a-fA-F]{2})([0-9a-fA-F]{2})?|#(?<rs>[0-9a-fA-F])(?<gs>[0-9a-fA-F])(?<bs>[0-9a-fA-F])\s*$/
|
||||
static keysSeparator = /[\.\(\)]/
|
||||
static indentation = " "
|
||||
static knotOffset = [-26, -16]
|
||||
static linkCurveHeight = 15 // px
|
||||
static linkCurveWidth = 80 // px
|
||||
@@ -922,10 +923,19 @@ class IEntity {
|
||||
const Self = /** @type {EntityConstructor} */(this.constructor);
|
||||
let attributes = Self.attributes;
|
||||
if (values.attributes) {
|
||||
let attributes = { ...Self.attributes };
|
||||
Utility.mergeArrays(Object.keys(attributes), Object.keys(values.attributes))
|
||||
.forEach(k => attributes[k] = {
|
||||
...attributes[k],
|
||||
...values.attributes[k]
|
||||
.forEach(k => {
|
||||
attributes[k] = {
|
||||
...IEntity.defaultAttribute,
|
||||
...attributes[k],
|
||||
...values.attributes[k]
|
||||
};
|
||||
if (!attributes[k].type) {
|
||||
attributes[k].type = values[k] instanceof Array
|
||||
? [Utility.getType(values[k][0])]
|
||||
: Utility.getType(values[k]);
|
||||
}
|
||||
});
|
||||
IEntity.defineAttributes(this, attributes);
|
||||
}
|
||||
@@ -2596,11 +2606,9 @@ class SVGIcon {
|
||||
`
|
||||
}
|
||||
|
||||
/** @typedef {import("./IEntity.js").AnyValue} AnyValue */
|
||||
class UnknownPinEntity extends PinEntity {
|
||||
|
||||
class UserDefinedPinEntity extends IEntity {
|
||||
|
||||
static lookbehind = "UserDefinedPin"
|
||||
static lookbehind = ""
|
||||
}
|
||||
|
||||
class VariableReferenceEntity extends IEntity {
|
||||
@@ -2806,6 +2814,7 @@ class ObjectEntity extends IEntity {
|
||||
},
|
||||
NodeGuid: {
|
||||
type: GuidEntity,
|
||||
showDefault: false,
|
||||
},
|
||||
ErrorType: {
|
||||
type: IntegerEntity,
|
||||
@@ -2817,7 +2826,7 @@ class ObjectEntity extends IEntity {
|
||||
showDefault: false,
|
||||
},
|
||||
CustomProperties: {
|
||||
type: [new UnionType(PinEntity, UserDefinedPinEntity)]
|
||||
type: [new UnionType(PinEntity, UnknownPinEntity)]
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2918,7 +2927,7 @@ class ObjectEntity extends IEntity {
|
||||
/** @type {GuidEntity} */ this.NodeGuid;
|
||||
/** @type {IntegerEntity?} */ this.ErrorType;
|
||||
/** @type {String?} */ this.ErrorMsg;
|
||||
/** @type {PinEntity[]} */ this.CustomProperties;
|
||||
/** @type {(PinEntity | UnknownPinEntity)[]} */ this.CustomProperties;
|
||||
}
|
||||
|
||||
getClass() {
|
||||
@@ -3355,7 +3364,7 @@ class Grammar {
|
||||
static DotSeparatedSymbols = Grammar.separatedBy(this.Symbol.source, "\\.")
|
||||
static PathFragment = Grammar.separatedBy(this.Symbol.source, "[\\.:]")
|
||||
static PathSpaceFragment = Grammar.separatedBy(this.Symbol.source, "[\\.:\\ ]")
|
||||
static Path = new RegExp(`(?:\\/${this.PathFragment.source}){2,}`)
|
||||
static Path = new RegExp(`(?:\\/${this.PathFragment.source}){2,}`) // Multiple (2+) /PathFragment
|
||||
static PathOptSpace = new RegExp(`(?:\\/${this.PathSpaceFragment.source}){2,}`)
|
||||
}
|
||||
|
||||
@@ -3384,12 +3393,21 @@ class Grammar {
|
||||
static colorValue = this.byteNumber
|
||||
static word = P.regex(Grammar.Regex.Word)
|
||||
static pathQuotes = Grammar.regexMap(
|
||||
new RegExp(`"(${Grammar.Regex.PathOptSpace.source}|${Grammar.Regex.Symbol.source})"|'"(${Grammar.Regex.PathOptSpace.source}|${Grammar.Regex.Symbol.source})"'`),
|
||||
new RegExp(
|
||||
`'(` + Grammar.Regex.PathOptSpace.source + `|` + Grammar.Regex.PathFragment.source + `)'`
|
||||
+ `|"(` + Grammar.Regex.PathOptSpace.source + `|` + Grammar.Regex.PathFragment.source + `)"`
|
||||
+ `|'"(` + Grammar.Regex.PathOptSpace.source + `|` + Grammar.Regex.PathFragment.source + `)"'`
|
||||
),
|
||||
([_0, a, b, c]) => a ?? b ?? c
|
||||
)
|
||||
static path = Grammar.regexMap(
|
||||
new RegExp(`(${Grammar.Regex.Path.source})|"(${Grammar.Regex.PathOptSpace.source})"|'"(${Grammar.Regex.PathOptSpace.source})"'`),
|
||||
([_0, a, b, c]) => a ?? b ?? c
|
||||
new RegExp(
|
||||
`(` + Grammar.Regex.Path.source + `)`
|
||||
+ `|'(` + Grammar.Regex.PathOptSpace.source + `)'`
|
||||
+ `|"(` + Grammar.Regex.PathOptSpace.source + `)"`
|
||||
+ `|'"(` + Grammar.Regex.PathOptSpace.source + `)"'`
|
||||
),
|
||||
([_0, a, b, c, d]) => a ?? b ?? c ?? d
|
||||
)
|
||||
static symbol = P.regex(Grammar.Regex.Symbol)
|
||||
static attributeName = P.regex(Grammar.Regex.DotSeparatedSymbols)
|
||||
@@ -3534,8 +3552,8 @@ class Grammar {
|
||||
case UnknownKeysEntity:
|
||||
result = this.unknownKeysEntity;
|
||||
break
|
||||
case UserDefinedPinEntity:
|
||||
result = this.userDefinedPinEntity;
|
||||
case UnknownPinEntity:
|
||||
result = this.unknownPinEntity;
|
||||
break
|
||||
case VariableReferenceEntity:
|
||||
result = this.variableReferenceEntity;
|
||||
@@ -3811,8 +3829,6 @@ class Grammar {
|
||||
|
||||
static symbolEntity = P.lazy(() => this.symbol.map(v => new SymbolEntity(v)))
|
||||
|
||||
static userDefinedPinEntity = P.lazy(() => this.createEntityGrammar(UserDefinedPinEntity))
|
||||
|
||||
static variableReferenceEntity = P.lazy(() => this.createEntityGrammar(VariableReferenceEntity))
|
||||
|
||||
static vector2DEntity = P.lazy(() => this.createEntityGrammar(Vector2DEntity, false))
|
||||
@@ -3838,14 +3854,33 @@ class Grammar {
|
||||
)
|
||||
.map(([lookbehind, attributes, _2]) => {
|
||||
let values = {};
|
||||
attributes.forEach(attributeSetter => attributeSetter(values));
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind;
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values));
|
||||
return new UnknownKeysEntity(values)
|
||||
})
|
||||
)
|
||||
|
||||
static unknownPinEntity = P.lazy(() =>
|
||||
P.seq(
|
||||
this.regexMap(
|
||||
new RegExp(`${this.Regex.Symbol.source}\\s*\\(\\s*`),
|
||||
result => result[1] ?? ""
|
||||
),
|
||||
this.createAttributeGrammar(this.unknownPinEntity).sepBy1(this.commaSeparation),
|
||||
P.regex(/\s*(?:,\s*)?\)/)
|
||||
)
|
||||
.map(([lookbehind, attributes, _2]) => {
|
||||
let values = {};
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind;
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values));
|
||||
return new UnknownPinEntity(values)
|
||||
})
|
||||
)
|
||||
|
||||
static unknownValue = P.lazy(() =>
|
||||
P.alt(
|
||||
// Remember to keep the order, otherwise parsing might fail
|
||||
@@ -3891,10 +3926,18 @@ class Grammar {
|
||||
v => v[1]
|
||||
)
|
||||
)
|
||||
.chain(([symbol, _1]) =>
|
||||
.chain(([symbol, index]) =>
|
||||
this.grammarFor(ObjectEntity.attributes[symbol])
|
||||
.map(currentValue =>
|
||||
values => (values[symbol] ??= []).push(currentValue)
|
||||
values => {
|
||||
(values[symbol] ??= [])[index] = currentValue;
|
||||
if (!ObjectEntity.attributes[symbol]?.inlined) {
|
||||
if (!values.attributes) {
|
||||
IEntity.defineAttributes(values, {});
|
||||
}
|
||||
Utility.objectSet(values, ["attributes", symbol, "inlined"], true, true);
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -4032,15 +4075,20 @@ class Grammar {
|
||||
/** @template {AnyValue} T */
|
||||
class Serializer {
|
||||
|
||||
/** @type {(v: String) => String} */
|
||||
static bracketsWrapped = (v => `(${v})`)
|
||||
/** @type {(v: String) => String} */
|
||||
static same = v => v
|
||||
|
||||
/** @type {(entity: AnyValue, serialized: String) => String} */
|
||||
static notWrapped = (entity, serialized) => serialized
|
||||
|
||||
/** @type {(entity: AnyValue, serialized: String) => String} */
|
||||
static bracketsWrapped = (entity, serialized) => `(${serialized})`
|
||||
|
||||
/** @param {AnyValueConstructor} entityType */
|
||||
constructor(
|
||||
entityType,
|
||||
wrap = Serializer.same,
|
||||
/** @type {(entity: T, serialized: String) => String} */
|
||||
wrap = (entity, serialized) => serialized,
|
||||
attributeSeparator = ",",
|
||||
trailingSeparator = false,
|
||||
attributeValueConjunctionSign = "=",
|
||||
@@ -4087,7 +4135,8 @@ class Serializer {
|
||||
*/
|
||||
doWrite(
|
||||
entity,
|
||||
insideString,
|
||||
insideString = false,
|
||||
indentation = "",
|
||||
wrap = this.wrap,
|
||||
attributeSeparator = this.attributeSeparator,
|
||||
trailingSeparator = this.trailingSeparator,
|
||||
@@ -4104,6 +4153,7 @@ class Serializer {
|
||||
for (const key of keys) {
|
||||
const value = entity[key];
|
||||
if (value !== undefined && this.showProperty(entity, key)) {
|
||||
const keyValue = entity instanceof Array ? `(${key})` : key;
|
||||
const isSerialized = Utility.isSerialized(entity, key);
|
||||
if (first) {
|
||||
first = false;
|
||||
@@ -4111,11 +4161,11 @@ class Serializer {
|
||||
result += attributeSeparator;
|
||||
}
|
||||
if (attributes[key]?.inlined) {
|
||||
const keyValue = entity instanceof Array ? `(${key})` : key;
|
||||
result += this.doWrite(
|
||||
value,
|
||||
insideString,
|
||||
Serializer.same,
|
||||
indentation,
|
||||
Serializer.notWrapped,
|
||||
attributeSeparator,
|
||||
false,
|
||||
attributeValueConjunctionSign,
|
||||
@@ -4125,13 +4175,17 @@ class Serializer {
|
||||
);
|
||||
continue
|
||||
}
|
||||
result +=
|
||||
attributeKeyPrinter(key)
|
||||
+ this.attributeValueConjunctionSign
|
||||
const keyPrinted = attributeKeyPrinter(keyValue);
|
||||
const indentationPrinted = attributeSeparator.includes("\n") ? indentation : "";
|
||||
result += (
|
||||
keyPrinted.length
|
||||
? (indentationPrinted + keyPrinted + this.attributeValueConjunctionSign)
|
||||
: ""
|
||||
)
|
||||
+ (
|
||||
isSerialized
|
||||
? `"${this.doWriteValue(value, true)}"`
|
||||
: this.doWriteValue(value, insideString)
|
||||
? `"${this.doWriteValue(value, true, indentation)}"`
|
||||
: this.doWriteValue(value, insideString, indentation)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4139,11 +4193,11 @@ class Serializer {
|
||||
// append separator at the end if asked and there was printed content
|
||||
result += attributeSeparator;
|
||||
}
|
||||
return wrap(result, entity.constructor)
|
||||
return wrap(entity, result)
|
||||
}
|
||||
|
||||
/** @param {Boolean} insideString */
|
||||
doWriteValue(value, insideString) {
|
||||
doWriteValue(value, insideString, indentation = "") {
|
||||
const type = Utility.getType(value);
|
||||
// @ts-expect-error
|
||||
const serializer = SerializerFactory.getSerializer(type);
|
||||
@@ -4153,10 +4207,7 @@ class Serializer {
|
||||
+ "check initializeSerializerFactory.js"
|
||||
)
|
||||
}
|
||||
return serializer.doWrite(
|
||||
value,
|
||||
insideString
|
||||
)
|
||||
return serializer.doWrite(value, insideString, indentation)
|
||||
}
|
||||
|
||||
showProperty(entity, key) {
|
||||
@@ -4167,7 +4218,7 @@ class Serializer {
|
||||
if (attribute.ignored) {
|
||||
return false
|
||||
}
|
||||
return !Utility.equals(attribute.value, value) || attribute.showDefault
|
||||
return !Utility.equals(attribute.default, value) || attribute.showDefault
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -4176,7 +4227,7 @@ class Serializer {
|
||||
class ObjectSerializer extends Serializer {
|
||||
|
||||
constructor() {
|
||||
super(ObjectEntity, undefined, "\n", false, undefined, k => ` ${k}`);
|
||||
super(ObjectEntity, undefined, "\n", true, undefined, Serializer.same);
|
||||
}
|
||||
|
||||
showProperty(entity, key) {
|
||||
@@ -4190,6 +4241,11 @@ class ObjectSerializer extends Serializer {
|
||||
return super.showProperty(entity, key)
|
||||
}
|
||||
|
||||
/** @param {ObjectEntity} value */
|
||||
write(value, insideString = false) {
|
||||
return this.doWrite(value, insideString) + "\n"
|
||||
}
|
||||
|
||||
/** @param {String} value */
|
||||
doRead(value) {
|
||||
const parseResult = Grammar.objectEntity.parse(value);
|
||||
@@ -4219,24 +4275,48 @@ class ObjectSerializer extends Serializer {
|
||||
doWrite(
|
||||
entity,
|
||||
insideString,
|
||||
indentation = "",
|
||||
wrap = this.wrap,
|
||||
attributeSeparator = this.attributeSeparator,
|
||||
trailingSeparator = this.trailingSeparator,
|
||||
attributeValueConjunctionSign = this.attributeValueConjunctionSign,
|
||||
attributeKeyPrinter = this.attributeKeyPrinter
|
||||
attributeKeyPrinter = this.attributeKeyPrinter,
|
||||
) {
|
||||
const moreIndentation = indentation + Configuration.indentation;
|
||||
if (!(entity instanceof ObjectEntity)) {
|
||||
return super.doWrite(entity, insideString)
|
||||
return super.doWrite(
|
||||
entity,
|
||||
insideString,
|
||||
indentation,
|
||||
wrap,
|
||||
attributeSeparator,
|
||||
trailingSeparator,
|
||||
attributeValueConjunctionSign,
|
||||
key => entity[key] instanceof ObjectEntity ? "" : attributeKeyPrinter(key)
|
||||
)
|
||||
}
|
||||
let result = `Begin Object Class=${entity.Class.path} Name=${this.doWriteValue(entity.Name, insideString)}\n`
|
||||
+ super.doWrite(entity, insideString)
|
||||
let result = indentation + "Begin Object"
|
||||
+ (entity.Class.path ? ` Class=${entity.Class.path}` : "")
|
||||
+ (entity.Name ? ` Name=${this.doWriteValue(entity.Name, insideString)}` : "")
|
||||
+ "\n"
|
||||
+ super.doWrite(
|
||||
entity,
|
||||
insideString,
|
||||
moreIndentation,
|
||||
wrap,
|
||||
attributeSeparator,
|
||||
true,
|
||||
attributeValueConjunctionSign,
|
||||
key => entity[key] instanceof ObjectEntity ? "" : attributeKeyPrinter(key)
|
||||
)
|
||||
+ entity.CustomProperties.map(pin =>
|
||||
this.attributeSeparator
|
||||
+ " CustomProperties "
|
||||
+ moreIndentation
|
||||
+ attributeKeyPrinter("CustomProperties ")
|
||||
+ SerializerFactory.getSerializer(PinEntity).doWrite(pin, insideString)
|
||||
)
|
||||
.join("")
|
||||
+ "\nEnd Object\n";
|
||||
+ indentation + "End Object";
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -10222,7 +10302,7 @@ class CustomSerializer extends Serializer {
|
||||
* @param {Boolean} insideString
|
||||
* @returns {String}
|
||||
*/
|
||||
doWrite(entity, insideString = false) {
|
||||
doWrite(entity, insideString, indentation = "") {
|
||||
let result = this.#objectWriter(entity, insideString);
|
||||
return result
|
||||
}
|
||||
@@ -10248,7 +10328,7 @@ class ToStringSerializer extends Serializer {
|
||||
* @param {T} entity
|
||||
* @param {Boolean} insideString
|
||||
*/
|
||||
doWrite(entity, insideString) {
|
||||
doWrite(entity, insideString, indentation = "") {
|
||||
return !insideString && entity.constructor === String
|
||||
? `"${Utility.escapeString(entity.toString())}"` // String will have quotes if not inside a string already
|
||||
: Utility.escapeString(entity.toString())
|
||||
@@ -10343,7 +10423,7 @@ function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
InvariantTextEntity,
|
||||
new Serializer(InvariantTextEntity, v => `${InvariantTextEntity.lookbehind}(${v})`, ", ", false, "", _ => "")
|
||||
new Serializer(InvariantTextEntity, (entity, v) => `${InvariantTextEntity.lookbehind}(${v})`, ", ", false, "", _ => "")
|
||||
);
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
@@ -10358,7 +10438,7 @@ function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
LocalizedTextEntity,
|
||||
new Serializer(LocalizedTextEntity, v => `${LocalizedTextEntity.lookbehind}(${v})`, ", ", false, "", _ => "")
|
||||
new Serializer(LocalizedTextEntity, (entity, v) => `${LocalizedTextEntity.lookbehind}(${v})`, ", ", false, "", _ => "")
|
||||
);
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
@@ -10395,12 +10475,12 @@ function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinEntity,
|
||||
new Serializer(PinEntity, v => `${PinEntity.lookbehind} (${v})`, ",", true)
|
||||
new Serializer(PinEntity, (entity, v) => `${PinEntity.lookbehind} (${v})`, ",", true)
|
||||
);
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinReferenceEntity,
|
||||
new Serializer(PinReferenceEntity, Serializer.same, " ", false, "", _ => "")
|
||||
new Serializer(PinReferenceEntity, undefined, " ", false, "", _ => "")
|
||||
);
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
@@ -10461,7 +10541,7 @@ function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
UnknownKeysEntity,
|
||||
new Serializer(UnknownKeysEntity, (string, entity) => `${entity.lookbehind ?? ""}(${string})`)
|
||||
new Serializer(UnknownKeysEntity, (entity, string) => `${entity.lookbehind ?? ""}(${string})`)
|
||||
);
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
|
||||
6
dist/ueblueprint.min.js
vendored
6
dist/ueblueprint.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -13,6 +13,7 @@
|
||||
padding: 0;
|
||||
--ueb-height: 100vh;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ export default class Configuration {
|
||||
static gridSize = 16 // px
|
||||
static hexColorRegex = /^\s*#(?<r>[0-9a-fA-F]{2})(?<g>[0-9a-fA-F]{2})(?<b>[0-9a-fA-F]{2})([0-9a-fA-F]{2})?|#(?<rs>[0-9a-fA-F])(?<gs>[0-9a-fA-F])(?<bs>[0-9a-fA-F])\s*$/
|
||||
static keysSeparator = /[\.\(\)]/
|
||||
static indentation = " "
|
||||
static knotOffset = [-26, -16]
|
||||
static linkCurveHeight = 15 // px
|
||||
static linkCurveWidth = 80 // px
|
||||
|
||||
@@ -49,10 +49,19 @@ export default class IEntity {
|
||||
const Self = /** @type {EntityConstructor} */(this.constructor)
|
||||
let attributes = Self.attributes
|
||||
if (values.attributes) {
|
||||
let attributes = { ...Self.attributes }
|
||||
Utility.mergeArrays(Object.keys(attributes), Object.keys(values.attributes))
|
||||
.forEach(k => attributes[k] = {
|
||||
...attributes[k],
|
||||
...values.attributes[k]
|
||||
.forEach(k => {
|
||||
attributes[k] = {
|
||||
...IEntity.defaultAttribute,
|
||||
...attributes[k],
|
||||
...values.attributes[k]
|
||||
}
|
||||
if (!attributes[k].type) {
|
||||
attributes[k].type = values[k] instanceof Array
|
||||
? [Utility.getType(values[k][0])]
|
||||
: Utility.getType(values[k])
|
||||
}
|
||||
})
|
||||
IEntity.defineAttributes(this, attributes)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import PinEntity from "./PinEntity.js"
|
||||
import SVGIcon from "../SVGIcon.js"
|
||||
import SymbolEntity from "./SymbolEntity.js"
|
||||
import UnionType from "./UnionType.js"
|
||||
import UserDefinedPinEntity from "./UserDefinedPinEntity.js"
|
||||
import UnknownPinEntity from "./UnknownPinEntity.js"
|
||||
import Utility from "../Utility.js"
|
||||
import VariableReferenceEntity from "./VariableReferenceEntity.js"
|
||||
|
||||
@@ -187,6 +187,7 @@ export default class ObjectEntity extends IEntity {
|
||||
},
|
||||
NodeGuid: {
|
||||
type: GuidEntity,
|
||||
showDefault: false,
|
||||
},
|
||||
ErrorType: {
|
||||
type: IntegerEntity,
|
||||
@@ -198,7 +199,7 @@ export default class ObjectEntity extends IEntity {
|
||||
showDefault: false,
|
||||
},
|
||||
CustomProperties: {
|
||||
type: [new UnionType(PinEntity, UserDefinedPinEntity)]
|
||||
type: [new UnionType(PinEntity, UnknownPinEntity)]
|
||||
},
|
||||
}
|
||||
|
||||
@@ -299,7 +300,7 @@ export default class ObjectEntity extends IEntity {
|
||||
/** @type {GuidEntity} */ this.NodeGuid
|
||||
/** @type {IntegerEntity?} */ this.ErrorType
|
||||
/** @type {String?} */ this.ErrorMsg
|
||||
/** @type {PinEntity[]} */ this.CustomProperties
|
||||
/** @type {(PinEntity | UnknownPinEntity)[]} */ this.CustomProperties
|
||||
}
|
||||
|
||||
getClass() {
|
||||
|
||||
6
js/entity/UnknownPinEntity.js
Executable file
6
js/entity/UnknownPinEntity.js
Executable file
@@ -0,0 +1,6 @@
|
||||
import PinEntity from "./PinEntity.js"
|
||||
|
||||
export default class UnknownPinEntity extends PinEntity {
|
||||
|
||||
static lookbehind = ""
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import IEntity from "./IEntity.js"
|
||||
import PinEntity from "./PinEntity.js"
|
||||
|
||||
/** @typedef {import("./IEntity.js").AnyValue} AnyValue */
|
||||
|
||||
export default class UserDefinedPinEntity extends IEntity {
|
||||
|
||||
static lookbehind = "UserDefinedPin"
|
||||
}
|
||||
@@ -27,7 +27,7 @@ export default class CustomSerializer extends Serializer {
|
||||
* @param {Boolean} insideString
|
||||
* @returns {String}
|
||||
*/
|
||||
doWrite(entity, insideString = false) {
|
||||
doWrite(entity, insideString, indentation = "") {
|
||||
let result = this.#objectWriter(entity, insideString)
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import SymbolEntity from "../entity/SymbolEntity.js"
|
||||
import TerminalTypeEntity from "../entity/TerminalTypeEntity.js"
|
||||
import UnionType from "../entity/UnionType.js"
|
||||
import UnknownKeysEntity from "../entity/UnknownKeysEntity.js"
|
||||
import UserDefinedPinEntity from "../entity/UserDefinedPinEntity.js"
|
||||
import UnknownPinEntity from "../entity/UnknownPinEntity.js"
|
||||
import Utility from "../Utility.js"
|
||||
import VariableReferenceEntity from "../entity/VariableReferenceEntity.js"
|
||||
import Vector2DEntity from "../entity/Vector2DEntity.js"
|
||||
@@ -71,7 +71,7 @@ export default class Grammar {
|
||||
static DotSeparatedSymbols = Grammar.separatedBy(this.Symbol.source, "\\.")
|
||||
static PathFragment = Grammar.separatedBy(this.Symbol.source, "[\\.:]")
|
||||
static PathSpaceFragment = Grammar.separatedBy(this.Symbol.source, "[\\.:\\ ]")
|
||||
static Path = new RegExp(`(?:\\/${this.PathFragment.source}){2,}`)
|
||||
static Path = new RegExp(`(?:\\/${this.PathFragment.source}){2,}`) // Multiple (2+) /PathFragment
|
||||
static PathOptSpace = new RegExp(`(?:\\/${this.PathSpaceFragment.source}){2,}`)
|
||||
}
|
||||
|
||||
@@ -100,12 +100,21 @@ export default class Grammar {
|
||||
static colorValue = this.byteNumber
|
||||
static word = P.regex(Grammar.Regex.Word)
|
||||
static pathQuotes = Grammar.regexMap(
|
||||
new RegExp(`"(${Grammar.Regex.PathOptSpace.source}|${Grammar.Regex.Symbol.source})"|'"(${Grammar.Regex.PathOptSpace.source}|${Grammar.Regex.Symbol.source})"'`),
|
||||
new RegExp(
|
||||
`'(` + Grammar.Regex.PathOptSpace.source + `|` + Grammar.Regex.PathFragment.source + `)'`
|
||||
+ `|"(` + Grammar.Regex.PathOptSpace.source + `|` + Grammar.Regex.PathFragment.source + `)"`
|
||||
+ `|'"(` + Grammar.Regex.PathOptSpace.source + `|` + Grammar.Regex.PathFragment.source + `)"'`
|
||||
),
|
||||
([_0, a, b, c]) => a ?? b ?? c
|
||||
)
|
||||
static path = Grammar.regexMap(
|
||||
new RegExp(`(${Grammar.Regex.Path.source})|"(${Grammar.Regex.PathOptSpace.source})"|'"(${Grammar.Regex.PathOptSpace.source})"'`),
|
||||
([_0, a, b, c]) => a ?? b ?? c
|
||||
new RegExp(
|
||||
`(` + Grammar.Regex.Path.source + `)`
|
||||
+ `|'(` + Grammar.Regex.PathOptSpace.source + `)'`
|
||||
+ `|"(` + Grammar.Regex.PathOptSpace.source + `)"`
|
||||
+ `|'"(` + Grammar.Regex.PathOptSpace.source + `)"'`
|
||||
),
|
||||
([_0, a, b, c, d]) => a ?? b ?? c ?? d
|
||||
)
|
||||
static symbol = P.regex(Grammar.Regex.Symbol)
|
||||
static attributeName = P.regex(Grammar.Regex.DotSeparatedSymbols)
|
||||
@@ -250,8 +259,8 @@ export default class Grammar {
|
||||
case UnknownKeysEntity:
|
||||
result = this.unknownKeysEntity
|
||||
break
|
||||
case UserDefinedPinEntity:
|
||||
result = this.userDefinedPinEntity
|
||||
case UnknownPinEntity:
|
||||
result = this.unknownPinEntity
|
||||
break
|
||||
case VariableReferenceEntity:
|
||||
result = this.variableReferenceEntity
|
||||
@@ -527,8 +536,6 @@ export default class Grammar {
|
||||
|
||||
static symbolEntity = P.lazy(() => this.symbol.map(v => new SymbolEntity(v)))
|
||||
|
||||
static userDefinedPinEntity = P.lazy(() => this.createEntityGrammar(UserDefinedPinEntity))
|
||||
|
||||
static variableReferenceEntity = P.lazy(() => this.createEntityGrammar(VariableReferenceEntity))
|
||||
|
||||
static vector2DEntity = P.lazy(() => this.createEntityGrammar(Vector2DEntity, false))
|
||||
@@ -554,14 +561,33 @@ export default class Grammar {
|
||||
)
|
||||
.map(([lookbehind, attributes, _2]) => {
|
||||
let values = {}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
return new UnknownKeysEntity(values)
|
||||
})
|
||||
)
|
||||
|
||||
static unknownPinEntity = P.lazy(() =>
|
||||
P.seq(
|
||||
this.regexMap(
|
||||
new RegExp(`${this.Regex.Symbol.source}\\s*\\(\\s*`),
|
||||
result => result[1] ?? ""
|
||||
),
|
||||
this.createAttributeGrammar(this.unknownPinEntity).sepBy1(this.commaSeparation),
|
||||
P.regex(/\s*(?:,\s*)?\)/)
|
||||
)
|
||||
.map(([lookbehind, attributes, _2]) => {
|
||||
let values = {}
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
return new UnknownPinEntity(values)
|
||||
})
|
||||
)
|
||||
|
||||
static unknownValue = P.lazy(() =>
|
||||
P.alt(
|
||||
// Remember to keep the order, otherwise parsing might fail
|
||||
@@ -607,10 +633,18 @@ export default class Grammar {
|
||||
v => v[1]
|
||||
)
|
||||
)
|
||||
.chain(([symbol, _1]) =>
|
||||
.chain(([symbol, index]) =>
|
||||
this.grammarFor(ObjectEntity.attributes[symbol])
|
||||
.map(currentValue =>
|
||||
values => (values[symbol] ??= []).push(currentValue)
|
||||
values => {
|
||||
(values[symbol] ??= [])[index] = currentValue
|
||||
if (!ObjectEntity.attributes[symbol]?.inlined) {
|
||||
if (!values.attributes) {
|
||||
IEntity.defineAttributes(values, {})
|
||||
}
|
||||
Utility.objectSet(values, ["attributes", symbol, "inlined"], true, true)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import Configuration from "../Configuration.js"
|
||||
import Grammar from "./Grammar.js"
|
||||
import Serializer from "./Serializer.js"
|
||||
import ObjectEntity from "../entity/ObjectEntity.js"
|
||||
import PinEntity from "../entity/PinEntity.js"
|
||||
import Serializer from "./Serializer.js"
|
||||
import SerializerFactory from "./SerializerFactory.js"
|
||||
|
||||
export default class ObjectSerializer extends Serializer {
|
||||
|
||||
constructor() {
|
||||
super(ObjectEntity, undefined, "\n", false, undefined, k => ` ${k}`)
|
||||
super(ObjectEntity, undefined, "\n", true, undefined, Serializer.same)
|
||||
}
|
||||
|
||||
showProperty(entity, key) {
|
||||
@@ -21,6 +22,11 @@ export default class ObjectSerializer extends Serializer {
|
||||
return super.showProperty(entity, key)
|
||||
}
|
||||
|
||||
/** @param {ObjectEntity} value */
|
||||
write(value, insideString = false) {
|
||||
return this.doWrite(value, insideString) + "\n"
|
||||
}
|
||||
|
||||
/** @param {String} value */
|
||||
doRead(value) {
|
||||
const parseResult = Grammar.objectEntity.parse(value)
|
||||
@@ -50,24 +56,48 @@ export default class ObjectSerializer extends Serializer {
|
||||
doWrite(
|
||||
entity,
|
||||
insideString,
|
||||
indentation = "",
|
||||
wrap = this.wrap,
|
||||
attributeSeparator = this.attributeSeparator,
|
||||
trailingSeparator = this.trailingSeparator,
|
||||
attributeValueConjunctionSign = this.attributeValueConjunctionSign,
|
||||
attributeKeyPrinter = this.attributeKeyPrinter
|
||||
attributeKeyPrinter = this.attributeKeyPrinter,
|
||||
) {
|
||||
const moreIndentation = indentation + Configuration.indentation
|
||||
if (!(entity instanceof ObjectEntity)) {
|
||||
return super.doWrite(entity, insideString)
|
||||
return super.doWrite(
|
||||
entity,
|
||||
insideString,
|
||||
indentation,
|
||||
wrap,
|
||||
attributeSeparator,
|
||||
trailingSeparator,
|
||||
attributeValueConjunctionSign,
|
||||
key => entity[key] instanceof ObjectEntity ? "" : attributeKeyPrinter(key)
|
||||
)
|
||||
}
|
||||
let result = `Begin Object Class=${entity.Class.path} Name=${this.doWriteValue(entity.Name, insideString)}\n`
|
||||
+ super.doWrite(entity, insideString)
|
||||
let result = indentation + "Begin Object"
|
||||
+ (entity.Class.path ? ` Class=${entity.Class.path}` : "")
|
||||
+ (entity.Name ? ` Name=${this.doWriteValue(entity.Name, insideString)}` : "")
|
||||
+ "\n"
|
||||
+ super.doWrite(
|
||||
entity,
|
||||
insideString,
|
||||
moreIndentation,
|
||||
wrap,
|
||||
attributeSeparator,
|
||||
true,
|
||||
attributeValueConjunctionSign,
|
||||
key => entity[key] instanceof ObjectEntity ? "" : attributeKeyPrinter(key)
|
||||
)
|
||||
+ entity.CustomProperties.map(pin =>
|
||||
this.attributeSeparator
|
||||
+ " CustomProperties "
|
||||
+ moreIndentation
|
||||
+ attributeKeyPrinter("CustomProperties ")
|
||||
+ SerializerFactory.getSerializer(PinEntity).doWrite(pin, insideString)
|
||||
)
|
||||
.join("")
|
||||
+ "\nEnd Object\n"
|
||||
+ indentation + "End Object"
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,20 @@ import Utility from "../Utility.js"
|
||||
/** @template {AnyValue} T */
|
||||
export default class Serializer {
|
||||
|
||||
/** @type {(v: String) => String} */
|
||||
static bracketsWrapped = (v => `(${v})`)
|
||||
/** @type {(v: String) => String} */
|
||||
static same = v => v
|
||||
|
||||
/** @type {(entity: AnyValue, serialized: String) => String} */
|
||||
static notWrapped = (entity, serialized) => serialized
|
||||
|
||||
/** @type {(entity: AnyValue, serialized: String) => String} */
|
||||
static bracketsWrapped = (entity, serialized) => `(${serialized})`
|
||||
|
||||
/** @param {AnyValueConstructor} entityType */
|
||||
constructor(
|
||||
entityType,
|
||||
wrap = Serializer.same,
|
||||
/** @type {(entity: T, serialized: String) => String} */
|
||||
wrap = (entity, serialized) => serialized,
|
||||
attributeSeparator = ",",
|
||||
trailingSeparator = false,
|
||||
attributeValueConjunctionSign = "=",
|
||||
@@ -67,7 +72,8 @@ export default class Serializer {
|
||||
*/
|
||||
doWrite(
|
||||
entity,
|
||||
insideString,
|
||||
insideString = false,
|
||||
indentation = "",
|
||||
wrap = this.wrap,
|
||||
attributeSeparator = this.attributeSeparator,
|
||||
trailingSeparator = this.trailingSeparator,
|
||||
@@ -95,7 +101,8 @@ export default class Serializer {
|
||||
result += this.doWrite(
|
||||
value,
|
||||
insideString,
|
||||
Serializer.same,
|
||||
indentation,
|
||||
Serializer.notWrapped,
|
||||
attributeSeparator,
|
||||
false,
|
||||
attributeValueConjunctionSign,
|
||||
@@ -105,13 +112,17 @@ export default class Serializer {
|
||||
)
|
||||
continue
|
||||
}
|
||||
result +=
|
||||
attributeKeyPrinter(keyValue)
|
||||
+ this.attributeValueConjunctionSign
|
||||
const keyPrinted = attributeKeyPrinter(keyValue)
|
||||
const indentationPrinted = attributeSeparator.includes("\n") ? indentation : ""
|
||||
result += (
|
||||
keyPrinted.length
|
||||
? (indentationPrinted + keyPrinted + this.attributeValueConjunctionSign)
|
||||
: ""
|
||||
)
|
||||
+ (
|
||||
isSerialized
|
||||
? `"${this.doWriteValue(value, true)}"`
|
||||
: this.doWriteValue(value, insideString)
|
||||
? `"${this.doWriteValue(value, true, indentation)}"`
|
||||
: this.doWriteValue(value, insideString, indentation)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -119,11 +130,11 @@ export default class Serializer {
|
||||
// append separator at the end if asked and there was printed content
|
||||
result += attributeSeparator
|
||||
}
|
||||
return wrap(result, entity.constructor)
|
||||
return wrap(entity, result)
|
||||
}
|
||||
|
||||
/** @param {Boolean} insideString */
|
||||
doWriteValue(value, insideString) {
|
||||
doWriteValue(value, insideString, indentation = "") {
|
||||
const type = Utility.getType(value)
|
||||
// @ts-expect-error
|
||||
const serializer = SerializerFactory.getSerializer(type)
|
||||
@@ -133,10 +144,7 @@ export default class Serializer {
|
||||
+ "check initializeSerializerFactory.js"
|
||||
)
|
||||
}
|
||||
return serializer.doWrite(
|
||||
value,
|
||||
insideString
|
||||
)
|
||||
return serializer.doWrite(value, insideString, indentation)
|
||||
}
|
||||
|
||||
showProperty(entity, key) {
|
||||
@@ -147,7 +155,7 @@ export default class Serializer {
|
||||
if (attribute.ignored) {
|
||||
return false
|
||||
}
|
||||
return !Utility.equals(attribute.value, value) || attribute.showDefault
|
||||
return !Utility.equals(attribute.default, value) || attribute.showDefault
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export default class ToStringSerializer extends Serializer {
|
||||
* @param {T} entity
|
||||
* @param {Boolean} insideString
|
||||
*/
|
||||
doWrite(entity, insideString) {
|
||||
doWrite(entity, insideString, indentation = "") {
|
||||
return !insideString && entity.constructor === String
|
||||
? `"${Utility.escapeString(entity.toString())}"` // String will have quotes if not inside a string already
|
||||
: Utility.escapeString(entity.toString())
|
||||
|
||||
@@ -121,7 +121,7 @@ export default function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
InvariantTextEntity,
|
||||
new Serializer(InvariantTextEntity, v => `${InvariantTextEntity.lookbehind}(${v})`, ", ", false, "", _ => "")
|
||||
new Serializer(InvariantTextEntity, (entity, v) => `${InvariantTextEntity.lookbehind}(${v})`, ", ", false, "", _ => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
@@ -136,7 +136,7 @@ export default function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
LocalizedTextEntity,
|
||||
new Serializer(LocalizedTextEntity, v => `${LocalizedTextEntity.lookbehind}(${v})`, ", ", false, "", _ => "")
|
||||
new Serializer(LocalizedTextEntity, (entity, v) => `${LocalizedTextEntity.lookbehind}(${v})`, ", ", false, "", _ => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
@@ -173,12 +173,12 @@ export default function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinEntity,
|
||||
new Serializer(PinEntity, v => `${PinEntity.lookbehind} (${v})`, ",", true)
|
||||
new Serializer(PinEntity, (entity, v) => `${PinEntity.lookbehind} (${v})`, ",", true)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinReferenceEntity,
|
||||
new Serializer(PinReferenceEntity, Serializer.same, " ", false, "", _ => "")
|
||||
new Serializer(PinReferenceEntity, undefined, " ", false, "", _ => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
@@ -239,7 +239,7 @@ export default function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
UnknownKeysEntity,
|
||||
new Serializer(UnknownKeysEntity, (string, entity) => `${entity.lookbehind ?? ""}(${string})`)
|
||||
new Serializer(UnknownKeysEntity, (entity, string) => `${entity.lookbehind ?? ""}(${string})`)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
|
||||
Reference in New Issue
Block a user