mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-06-18 18:43:55 +08:00
Serialization fixed
This commit is contained in:
119
dist/ueblueprint.js
vendored
119
dist/ueblueprint.js
vendored
@@ -1,4 +1,5 @@
|
|||||||
class Primitive {
|
class Primitive {
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
return "Unimplemented for " + this.constructor.name
|
return "Unimplemented for " + this.constructor.name
|
||||||
}
|
}
|
||||||
@@ -139,6 +140,7 @@ class Utility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Entity {
|
class Entity {
|
||||||
|
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -266,16 +268,28 @@ class LocalizedTextEntity extends Entity {
|
|||||||
getAttributes() {
|
getAttributes() {
|
||||||
return LocalizedTextEntity.attributes
|
return LocalizedTextEntity.attributes
|
||||||
}
|
}
|
||||||
|
}
|
||||||
toString() {
|
|
||||||
"NSLOCTEXT(" + `"${this.namespace}"` + ", " + `"${this.key}"` + ", " + `"${this.value}"` + ")";
|
class PathSymbol extends Primitive {
|
||||||
}
|
|
||||||
|
constructor(value) {
|
||||||
|
super();
|
||||||
|
this.value = new String(value).valueOf();
|
||||||
|
}
|
||||||
|
|
||||||
|
valueOf() {
|
||||||
|
this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return this.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PinReferenceEntity extends Entity {
|
class PinReferenceEntity extends Entity {
|
||||||
|
|
||||||
static attributes = {
|
static attributes = {
|
||||||
objectName: String,
|
objectName: PathSymbol,
|
||||||
pinGuid: Guid
|
pinGuid: Guid
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,8 +419,8 @@ class Grammar {
|
|||||||
String = _ => P.regex(/(?:[^"\\]|\\")*/).wrap(P.string('"'), P.string('"')).desc('string (with possibility to escape the quote using \")')
|
String = _ => P.regex(/(?:[^"\\]|\\")*/).wrap(P.string('"'), P.string('"')).desc('string (with possibility to escape the quote using \")')
|
||||||
Word = _ => P.regex(/[a-zA-Z]+/).desc("a word")
|
Word = _ => P.regex(/[a-zA-Z]+/).desc("a word")
|
||||||
Guid = _ => P.regex(/[0-9a-zA-Z]{32}/).map(v => new Guid(v)).desc("32 digit hexadecimal (accepts all the letters for safety) value")
|
Guid = _ => P.regex(/[0-9a-zA-Z]{32}/).map(v => new Guid(v)).desc("32 digit hexadecimal (accepts all the letters for safety) value")
|
||||||
PathSymbol = _ => P.regex(/[0-9a-zA-Z_]+/)
|
PathSymbol = _ => P.regex(/[0-9a-zA-Z_]+/).map(v => new PathSymbol(v))
|
||||||
ReferencePath = r => P.seq(P.string("/"), r.PathSymbol.sepBy1(P.string(".")).tieWith("."))
|
ReferencePath = r => P.seq(P.string("/"), r.PathSymbol.map(v => v.toString()).sepBy1(P.string(".")).tieWith("."))
|
||||||
.tie()
|
.tie()
|
||||||
.atLeast(2)
|
.atLeast(2)
|
||||||
.tie()
|
.tie()
|
||||||
@@ -591,6 +605,7 @@ class Serializer {
|
|||||||
if (value === null) {
|
if (value === null) {
|
||||||
return "()"
|
return "()"
|
||||||
}
|
}
|
||||||
|
const serialize = v => SerializerFactory.getSerializer(Utility.getType(v)).write(v);
|
||||||
// This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically)
|
// This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically)
|
||||||
switch (value?.constructor) {
|
switch (value?.constructor) {
|
||||||
case Function:
|
case Function:
|
||||||
@@ -602,8 +617,11 @@ class Serializer {
|
|||||||
case String:
|
case String:
|
||||||
return `"${value}"`
|
return `"${value}"`
|
||||||
}
|
}
|
||||||
|
if (value instanceof Array) {
|
||||||
|
return `(${value.map(v => serialize(v) + ",")})`
|
||||||
|
}
|
||||||
if (value instanceof Entity) {
|
if (value instanceof Entity) {
|
||||||
return SerializerFactory.getSerializer(Utility.getType(value)).write(value)
|
return serialize(value)
|
||||||
}
|
}
|
||||||
if (value instanceof Primitive) {
|
if (value instanceof Primitive) {
|
||||||
return value.toString()
|
return value.toString()
|
||||||
@@ -619,7 +637,8 @@ class Serializer {
|
|||||||
const value = object[property];
|
const value = object[property];
|
||||||
if (object[property]?.constructor === Object) {
|
if (object[property]?.constructor === Object) {
|
||||||
// Recursive call when finding an object
|
// Recursive call when finding an object
|
||||||
result += this.subWrite(fullKey, value, this.prefix, this.separator);
|
result += (result.length ? this.separator : "")
|
||||||
|
+ this.subWrite(fullKey, value);
|
||||||
} else if (this.showProperty(fullKey, value)) {
|
} else if (this.showProperty(fullKey, value)) {
|
||||||
result += (result.length ? this.separator : "")
|
result += (result.length ? this.separator : "")
|
||||||
+ this.prefix
|
+ this.prefix
|
||||||
@@ -628,7 +647,7 @@ class Serializer {
|
|||||||
+ this.writeValue(value);
|
+ this.writeValue(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.trailingSeparator && result.length) {
|
if (this.trailingSeparator && result.length && fullKey.length === 0) {
|
||||||
// append separator at the end if asked and there was printed content
|
// append separator at the end if asked and there was printed content
|
||||||
result += this.separator;
|
result += this.separator;
|
||||||
}
|
}
|
||||||
@@ -647,9 +666,9 @@ class Serializer {
|
|||||||
|
|
||||||
class GeneralSerializer extends Serializer {
|
class GeneralSerializer extends Serializer {
|
||||||
|
|
||||||
constructor(keyword, entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) {
|
constructor(wrap, entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) {
|
||||||
super(entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter);
|
super(entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter);
|
||||||
this.keyword = keyword ?? "";
|
this.wrap = wrap ?? (v => `(${v})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
read(value) {
|
read(value) {
|
||||||
@@ -663,7 +682,7 @@ class GeneralSerializer extends Serializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
write(object) {
|
write(object) {
|
||||||
let result = `${this.keyword}(${this.subWrite([], object)})`;
|
let result = this.wrap(this.subWrite([], object));
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -714,7 +733,7 @@ class ObjectSerializer extends Serializer {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
write(object) {
|
write(object) {
|
||||||
let result = `Begin Object Class=${object.Class} Name=${object.Name}
|
let result = `Begin Object Class=${object.Class} Name="${object.Name}"
|
||||||
${this.subWrite([], object)
|
${this.subWrite([], object)
|
||||||
+ object
|
+ object
|
||||||
.CustomProperties.map(pin => this.separator + this.prefix + "CustomProperties " + SerializerFactory.getSerializer(PinEntity).write(pin))
|
.CustomProperties.map(pin => this.separator + this.prefix + "CustomProperties " + SerializerFactory.getSerializer(PinEntity).write(pin))
|
||||||
@@ -1604,9 +1623,7 @@ class Paste extends Context {
|
|||||||
constructor(target, blueprint, options = {}) {
|
constructor(target, blueprint, options = {}) {
|
||||||
options.wantsFocusCallback = true;
|
options.wantsFocusCallback = true;
|
||||||
super(target, blueprint, options);
|
super(target, blueprint, options);
|
||||||
|
|
||||||
this.serializer = new ObjectSerializer();
|
this.serializer = new ObjectSerializer();
|
||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
this.pasteHandle = e => self.pasted(e.clipboardData.getData("Text"));
|
this.pasteHandle = e => self.pasted(e.clipboardData.getData("Text"));
|
||||||
}
|
}
|
||||||
@@ -1630,8 +1647,11 @@ class Paste extends Context {
|
|||||||
});
|
});
|
||||||
let mousePosition = this.blueprint.entity.mousePosition;
|
let mousePosition = this.blueprint.entity.mousePosition;
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
node.location[0] += mousePosition[0] - left;
|
const locationOffset = [
|
||||||
node.location[1] += mousePosition[1] - top;
|
mousePosition[0] - left,
|
||||||
|
mousePosition[1] - top
|
||||||
|
];
|
||||||
|
node.addLocation(locationOffset);
|
||||||
});
|
});
|
||||||
this.blueprint.addNode(...nodes);
|
this.blueprint.addNode(...nodes);
|
||||||
}
|
}
|
||||||
@@ -1747,6 +1767,30 @@ class Zoom extends MouseWheel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Copy extends Context {
|
||||||
|
|
||||||
|
constructor(target, blueprint, options = {}) {
|
||||||
|
options.wantsFocusCallback = true;
|
||||||
|
super(target, blueprint, options);
|
||||||
|
this.serializer = new ObjectSerializer();
|
||||||
|
let self = this;
|
||||||
|
this.copyHandle = _ => self.copied();
|
||||||
|
}
|
||||||
|
|
||||||
|
blueprintFocused() {
|
||||||
|
document.body.addEventListener("copy", this.copyHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
blueprintUnfocused() {
|
||||||
|
document.body.removeEventListener("copy", this.copyHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
copied() {
|
||||||
|
const value = this.blueprint.getNodes(true).map(node => this.serializer.write(node.entity)).join("\n");
|
||||||
|
navigator.clipboard.writeText(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @typedef {import("./graph/GraphNode").default} GraphNode */
|
/** @typedef {import("./graph/GraphNode").default} GraphNode */
|
||||||
class Blueprint extends GraphElement {
|
class Blueprint extends GraphElement {
|
||||||
|
|
||||||
@@ -1807,6 +1851,7 @@ class Blueprint extends GraphElement {
|
|||||||
this.querySelector('[data-nodes]').append(...this.entity.nodes);
|
this.querySelector('[data-nodes]').append(...this.entity.nodes);
|
||||||
|
|
||||||
|
|
||||||
|
this.copyObject = new Copy(this.getGridDOMElement(), this);
|
||||||
this.pasteObject = new Paste(this.getGridDOMElement(), this);
|
this.pasteObject = new Paste(this.getGridDOMElement(), this);
|
||||||
|
|
||||||
this.dragObject = new DragScroll(this.getGridDOMElement(), this, {
|
this.dragObject = new DragScroll(this.getGridDOMElement(), this, {
|
||||||
@@ -2027,8 +2072,18 @@ class Blueprint extends GraphElement {
|
|||||||
*
|
*
|
||||||
* @returns {GraphNode[]} Nodes
|
* @returns {GraphNode[]} Nodes
|
||||||
*/
|
*/
|
||||||
getNodes() {
|
getNodes(selected = false) {
|
||||||
return this.entity.nodes
|
if (selected) {
|
||||||
|
return this.entity.nodes.filter(
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {GraphNode} node
|
||||||
|
*/
|
||||||
|
node => node.selected
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return this.entity.nodes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2098,9 +2153,25 @@ class GraphLink extends GraphElement {
|
|||||||
|
|
||||||
customElements.define('u-link', GraphLink);
|
customElements.define('u-link', GraphLink);
|
||||||
|
|
||||||
SerializerFactory.registerSerializer(ObjectEntity, new ObjectSerializer());
|
SerializerFactory.registerSerializer(
|
||||||
SerializerFactory.registerSerializer(PinEntity, new GeneralSerializer("Pin ", PinEntity, "", ",", true));
|
ObjectEntity,
|
||||||
SerializerFactory.registerSerializer(FunctionReferenceEntity, new GeneralSerializer("", FunctionReferenceEntity, "", ",", false));
|
new ObjectSerializer()
|
||||||
SerializerFactory.registerSerializer(LocalizedTextEntity, new GeneralSerializer("NSLOCTEXT", LocalizedTextEntity, "", ",", false, "", _ => ""));
|
);
|
||||||
|
SerializerFactory.registerSerializer(
|
||||||
|
PinEntity,
|
||||||
|
new GeneralSerializer(v => `Pin (${v})`, PinEntity, "", ",", true)
|
||||||
|
);
|
||||||
|
SerializerFactory.registerSerializer(
|
||||||
|
FunctionReferenceEntity,
|
||||||
|
new GeneralSerializer(v => `(${v})`, FunctionReferenceEntity, "", ",", false)
|
||||||
|
);
|
||||||
|
SerializerFactory.registerSerializer(
|
||||||
|
LocalizedTextEntity,
|
||||||
|
new GeneralSerializer(v => `NSLOCTEXT(${v})`, LocalizedTextEntity, "", ",", false, "", _ => "")
|
||||||
|
);
|
||||||
|
SerializerFactory.registerSerializer(
|
||||||
|
PinReferenceEntity,
|
||||||
|
new GeneralSerializer(v => v, PinReferenceEntity, "", " ", false, "", _ => "")
|
||||||
|
);
|
||||||
|
|
||||||
export { Blueprint, GraphLink, GraphNode };
|
export { Blueprint, GraphLink, GraphNode };
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import Select from "./input/Select"
|
|||||||
import Unfocus from "./input/Unfocus"
|
import Unfocus from "./input/Unfocus"
|
||||||
import Utility from "./Utility"
|
import Utility from "./Utility"
|
||||||
import Zoom from "./input/Zoom"
|
import Zoom from "./input/Zoom"
|
||||||
|
import Copy from "./input/Copy"
|
||||||
|
|
||||||
/** @typedef {import("./graph/GraphNode").default} GraphNode */
|
/** @typedef {import("./graph/GraphNode").default} GraphNode */
|
||||||
export default class Blueprint extends GraphElement {
|
export default class Blueprint extends GraphElement {
|
||||||
@@ -70,6 +71,7 @@ export default class Blueprint extends GraphElement {
|
|||||||
this.querySelector('[data-nodes]').append(...this.entity.nodes)
|
this.querySelector('[data-nodes]').append(...this.entity.nodes)
|
||||||
|
|
||||||
|
|
||||||
|
this.copyObject = new Copy(this.getGridDOMElement(), this)
|
||||||
this.pasteObject = new Paste(this.getGridDOMElement(), this)
|
this.pasteObject = new Paste(this.getGridDOMElement(), this)
|
||||||
|
|
||||||
this.dragObject = new DragScroll(this.getGridDOMElement(), this, {
|
this.dragObject = new DragScroll(this.getGridDOMElement(), this, {
|
||||||
@@ -290,8 +292,18 @@ export default class Blueprint extends GraphElement {
|
|||||||
*
|
*
|
||||||
* @returns {GraphNode[]} Nodes
|
* @returns {GraphNode[]} Nodes
|
||||||
*/
|
*/
|
||||||
getNodes() {
|
getNodes(selected = false) {
|
||||||
return this.entity.nodes
|
if (selected) {
|
||||||
|
return this.entity.nodes.filter(
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {GraphNode} node
|
||||||
|
*/
|
||||||
|
node => node.selected
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return this.entity.nodes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,8 +11,4 @@ export default class LocalizedTextEntity extends Entity {
|
|||||||
getAttributes() {
|
getAttributes() {
|
||||||
return LocalizedTextEntity.attributes
|
return LocalizedTextEntity.attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
|
||||||
"NSLOCTEXT(" + `"${this.namespace}"` + ", " + `"${this.key}"` + ", " + `"${this.value}"` + ")"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import Entity from "./Entity"
|
import Entity from "./Entity"
|
||||||
import Guid from "./primitive/Guid"
|
import Guid from "./primitive/Guid"
|
||||||
|
import PathSymbol from "./primitive/PathSymbol"
|
||||||
|
|
||||||
export default class PinReferenceEntity extends Entity {
|
export default class PinReferenceEntity extends Entity {
|
||||||
|
|
||||||
static attributes = {
|
static attributes = {
|
||||||
objectName: String,
|
objectName: PathSymbol,
|
||||||
pinGuid: Guid
|
pinGuid: Guid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
js/entity/primitive/PathSymbol.js
Normal file
17
js/entity/primitive/PathSymbol.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import Primitive from "./Primitive";
|
||||||
|
|
||||||
|
export default class PathSymbol extends Primitive {
|
||||||
|
|
||||||
|
constructor(value) {
|
||||||
|
super()
|
||||||
|
this.value = new String(value).valueOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
valueOf() {
|
||||||
|
this.value
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return this.value
|
||||||
|
}
|
||||||
|
}
|
||||||
25
js/export.js
25
js/export.js
@@ -8,10 +8,27 @@ import SerializerFactory from "./serialization/SerializerFactory"
|
|||||||
import Blueprint from "./Blueprint"
|
import Blueprint from "./Blueprint"
|
||||||
import GraphNode from "./graph/GraphNode"
|
import GraphNode from "./graph/GraphNode"
|
||||||
import GraphLink from "./graph/GraphLink"
|
import GraphLink from "./graph/GraphLink"
|
||||||
|
import PinReferenceEntity from "./entity/PinReferenceEntity"
|
||||||
|
|
||||||
SerializerFactory.registerSerializer(ObjectEntity, new ObjectSerializer())
|
SerializerFactory.registerSerializer(
|
||||||
SerializerFactory.registerSerializer(PinEntity, new GeneralSerializer("Pin ", PinEntity, "", ",", true))
|
ObjectEntity,
|
||||||
SerializerFactory.registerSerializer(FunctionReferenceEntity, new GeneralSerializer("", FunctionReferenceEntity, "", ",", false))
|
new ObjectSerializer()
|
||||||
SerializerFactory.registerSerializer(LocalizedTextEntity, new GeneralSerializer("NSLOCTEXT", LocalizedTextEntity, "", ",", false, "", _ => ""))
|
)
|
||||||
|
SerializerFactory.registerSerializer(
|
||||||
|
PinEntity,
|
||||||
|
new GeneralSerializer(v => `Pin (${v})`, PinEntity, "", ",", true)
|
||||||
|
)
|
||||||
|
SerializerFactory.registerSerializer(
|
||||||
|
FunctionReferenceEntity,
|
||||||
|
new GeneralSerializer(v => `(${v})`, FunctionReferenceEntity, "", ",", false)
|
||||||
|
)
|
||||||
|
SerializerFactory.registerSerializer(
|
||||||
|
LocalizedTextEntity,
|
||||||
|
new GeneralSerializer(v => `NSLOCTEXT(${v})`, LocalizedTextEntity, "", ",", false, "", _ => "")
|
||||||
|
)
|
||||||
|
SerializerFactory.registerSerializer(
|
||||||
|
PinReferenceEntity,
|
||||||
|
new GeneralSerializer(v => v, PinReferenceEntity, "", " ", false, "", _ => "")
|
||||||
|
)
|
||||||
|
|
||||||
export { Blueprint as Blueprint, GraphNode as GraphNode, GraphLink as GraphLink }
|
export { Blueprint as Blueprint, GraphNode as GraphNode, GraphLink as GraphLink }
|
||||||
26
js/input/Copy.js
Normal file
26
js/input/Copy.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import Context from "./Context"
|
||||||
|
import ObjectSerializer from "../serialization/ObjectSerializer"
|
||||||
|
|
||||||
|
export default class Copy extends Context {
|
||||||
|
|
||||||
|
constructor(target, blueprint, options = {}) {
|
||||||
|
options.wantsFocusCallback = true
|
||||||
|
super(target, blueprint, options)
|
||||||
|
this.serializer = new ObjectSerializer()
|
||||||
|
let self = this
|
||||||
|
this.copyHandle = _ => self.copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
blueprintFocused() {
|
||||||
|
document.body.addEventListener("copy", this.copyHandle)
|
||||||
|
}
|
||||||
|
|
||||||
|
blueprintUnfocused() {
|
||||||
|
document.body.removeEventListener("copy", this.copyHandle)
|
||||||
|
}
|
||||||
|
|
||||||
|
copied() {
|
||||||
|
const value = this.blueprint.getNodes(true).map(node => this.serializer.write(node.entity)).join("\n")
|
||||||
|
navigator.clipboard.writeText(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,9 +7,7 @@ export default class Paste extends Context {
|
|||||||
constructor(target, blueprint, options = {}) {
|
constructor(target, blueprint, options = {}) {
|
||||||
options.wantsFocusCallback = true
|
options.wantsFocusCallback = true
|
||||||
super(target, blueprint, options)
|
super(target, blueprint, options)
|
||||||
|
|
||||||
this.serializer = new ObjectSerializer()
|
this.serializer = new ObjectSerializer()
|
||||||
|
|
||||||
let self = this
|
let self = this
|
||||||
this.pasteHandle = e => self.pasted(e.clipboardData.getData("Text"))
|
this.pasteHandle = e => self.pasted(e.clipboardData.getData("Text"))
|
||||||
}
|
}
|
||||||
@@ -33,8 +31,11 @@ export default class Paste extends Context {
|
|||||||
})
|
})
|
||||||
let mousePosition = this.blueprint.entity.mousePosition
|
let mousePosition = this.blueprint.entity.mousePosition
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
node.location[0] += mousePosition[0] - left
|
const locationOffset = [
|
||||||
node.location[1] += mousePosition[1] - top
|
mousePosition[0] - left,
|
||||||
|
mousePosition[1] - top
|
||||||
|
]
|
||||||
|
node.addLocation(locationOffset)
|
||||||
})
|
})
|
||||||
this.blueprint.addNode(...nodes)
|
this.blueprint.addNode(...nodes)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import Serializer from "./Serializer"
|
|||||||
|
|
||||||
export default class GeneralSerializer extends Serializer {
|
export default class GeneralSerializer extends Serializer {
|
||||||
|
|
||||||
constructor(keyword, entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) {
|
constructor(wrap, entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) {
|
||||||
super(entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter)
|
super(entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter)
|
||||||
this.keyword = keyword ?? ""
|
this.wrap = wrap ?? (v => `(${v})`)
|
||||||
}
|
}
|
||||||
|
|
||||||
read(value) {
|
read(value) {
|
||||||
@@ -19,7 +19,7 @@ export default class GeneralSerializer extends Serializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
write(object) {
|
write(object) {
|
||||||
let result = `${this.keyword}(${this.subWrite([], object)})`
|
let result = this.wrap(this.subWrite([], object))
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import Parsimmon from "parsimmon"
|
|||||||
import PinEntity from "../entity/PinEntity"
|
import PinEntity from "../entity/PinEntity"
|
||||||
import PinReferenceEntity from "../entity/PinReferenceEntity"
|
import PinReferenceEntity from "../entity/PinReferenceEntity"
|
||||||
import Utility from "../Utility"
|
import Utility from "../Utility"
|
||||||
|
import PathSymbol from "../entity/primitive/PathSymbol"
|
||||||
|
|
||||||
let P = Parsimmon
|
let P = Parsimmon
|
||||||
|
|
||||||
@@ -24,8 +25,8 @@ export default class Grammar {
|
|||||||
String = _ => P.regex(/(?:[^"\\]|\\")*/).wrap(P.string('"'), P.string('"')).desc('string (with possibility to escape the quote using \")')
|
String = _ => P.regex(/(?:[^"\\]|\\")*/).wrap(P.string('"'), P.string('"')).desc('string (with possibility to escape the quote using \")')
|
||||||
Word = _ => P.regex(/[a-zA-Z]+/).desc("a word")
|
Word = _ => P.regex(/[a-zA-Z]+/).desc("a word")
|
||||||
Guid = _ => P.regex(/[0-9a-zA-Z]{32}/).map(v => new Guid(v)).desc("32 digit hexadecimal (accepts all the letters for safety) value")
|
Guid = _ => P.regex(/[0-9a-zA-Z]{32}/).map(v => new Guid(v)).desc("32 digit hexadecimal (accepts all the letters for safety) value")
|
||||||
PathSymbol = _ => P.regex(/[0-9a-zA-Z_]+/)
|
PathSymbol = _ => P.regex(/[0-9a-zA-Z_]+/).map(v => new PathSymbol(v))
|
||||||
ReferencePath = r => P.seq(P.string("/"), r.PathSymbol.sepBy1(P.string(".")).tieWith("."))
|
ReferencePath = r => P.seq(P.string("/"), r.PathSymbol.map(v => v.toString()).sepBy1(P.string(".")).tieWith("."))
|
||||||
.tie()
|
.tie()
|
||||||
.atLeast(2)
|
.atLeast(2)
|
||||||
.tie()
|
.tie()
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default class ObjectSerializer extends Serializer {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
write(object) {
|
write(object) {
|
||||||
let result = `Begin Object Class=${object.Class} Name=${object.Name}
|
let result = `Begin Object Class=${object.Class} Name="${object.Name}"
|
||||||
${this.subWrite([], object)
|
${this.subWrite([], object)
|
||||||
+ object
|
+ object
|
||||||
.CustomProperties.map(pin => this.separator + this.prefix + "CustomProperties " + SerializerFactory.getSerializer(PinEntity).write(pin))
|
.CustomProperties.map(pin => this.separator + this.prefix + "CustomProperties " + SerializerFactory.getSerializer(PinEntity).write(pin))
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export default class Serializer {
|
|||||||
if (value === null) {
|
if (value === null) {
|
||||||
return "()"
|
return "()"
|
||||||
}
|
}
|
||||||
|
const serialize = v => SerializerFactory.getSerializer(Utility.getType(v)).write(v)
|
||||||
// This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically)
|
// This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically)
|
||||||
switch (value?.constructor) {
|
switch (value?.constructor) {
|
||||||
case Function:
|
case Function:
|
||||||
@@ -34,8 +35,11 @@ export default class Serializer {
|
|||||||
case String:
|
case String:
|
||||||
return `"${value}"`
|
return `"${value}"`
|
||||||
}
|
}
|
||||||
|
if (value instanceof Array) {
|
||||||
|
return `(${value.map(v => serialize(v) + ",")})`
|
||||||
|
}
|
||||||
if (value instanceof Entity) {
|
if (value instanceof Entity) {
|
||||||
return SerializerFactory.getSerializer(Utility.getType(value)).write(value)
|
return serialize(value)
|
||||||
}
|
}
|
||||||
if (value instanceof Primitive) {
|
if (value instanceof Primitive) {
|
||||||
return value.toString()
|
return value.toString()
|
||||||
@@ -51,7 +55,8 @@ export default class Serializer {
|
|||||||
const value = object[property]
|
const value = object[property]
|
||||||
if (object[property]?.constructor === Object) {
|
if (object[property]?.constructor === Object) {
|
||||||
// Recursive call when finding an object
|
// Recursive call when finding an object
|
||||||
result += this.subWrite(fullKey, value, this.prefix, this.separator)
|
result += (result.length ? this.separator : "")
|
||||||
|
+ this.subWrite(fullKey, value)
|
||||||
} else if (this.showProperty(fullKey, value)) {
|
} else if (this.showProperty(fullKey, value)) {
|
||||||
result += (result.length ? this.separator : "")
|
result += (result.length ? this.separator : "")
|
||||||
+ this.prefix
|
+ this.prefix
|
||||||
@@ -60,7 +65,7 @@ export default class Serializer {
|
|||||||
+ this.writeValue(value)
|
+ this.writeValue(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.trailingSeparator && result.length) {
|
if (this.trailingSeparator && result.length && fullKey.length === 0) {
|
||||||
// append separator at the end if asked and there was printed content
|
// append separator at the end if asked and there was printed content
|
||||||
result += this.separator
|
result += this.separator
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user