Small refactoring

This commit is contained in:
barsdeveloper
2021-12-11 23:58:40 +01:00
parent 6b02ab7e08
commit a5c4f04f2b
11 changed files with 235 additions and 150 deletions

View File

@@ -285,8 +285,8 @@ u-blueprint[data-focused="true"] .ueb-viewport-body {
margin-right: auto;
}
.ueb-node-input,
.ueb-node-output {
u-pin {
display: block;
padding: 4px 8px;
cursor: pointer;
}

191
dist/ueblueprint.js vendored
View File

@@ -974,7 +974,7 @@ class PinReferenceEntity extends Entity {
}
}
class PinEntity extends Entity {
class PinEntity$1 extends Entity {
static attributes = {
PinId: GuidEntity,
@@ -1007,23 +1007,7 @@ class PinEntity extends Entity {
}
getAttributes() {
return PinEntity.attributes
}
/**
*
* @returns {String}
*/
getPinDisplayName() {
return this.PinName
}
isConnected() {
return this.LinkedTo.length > 0
}
getType() {
return this.PinType.PinCategory ?? "object"
return PinEntity$1.attributes
}
isInput() {
@@ -1037,6 +1021,14 @@ class PinEntity extends Entity {
return true
}
}
isConnected() {
return this.LinkedTo.length > 0
}
getType() {
return this.PinType.PinCategory ?? "object"
}
}
/**
@@ -1066,6 +1058,83 @@ class SelectableDraggableTemplate extends Template {
}
}
/**
* @typedef {import("../graph/GraphPin").default} GraphPin
*/
class PinTemplate extends Template {
/**
* Computes the html content of the pin.
* @param {GraphPin} pin Pin entity
* @returns The result html
*/
render(pin) {
if (pin.isInput()) {
return html`
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
${pin.getPinDisplayName()}
`
} else {
return html`
${pin.getPinDisplayName()}
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
`
}
}
/**
* Applies the style to the element.
* @param {GraphPin} pin Element of the graph
*/
apply(pin) {
super.apply(pin);
pin.classList.add("ueb-node-" + pin.isInput() ? "input" : "output", "ueb-node-value-" + pin.getType());
}
}
class GraphPin extends GraphElement {
constructor(entity) {
super(entity, new PinTemplate());
/** @type {import("../entity/PinEntity").default} */
this.entity;
}
connectedCallback() {
super.connectedCallback();
}
/**
*
* @returns {String}
*/
getPinDisplayName() {
return this.entity.PinName
}
getAttributes() {
return PinEntity.attributes
}
isInput() {
return this.entity.isInput()
}
isOutput() {
return this.entity.isOutput()
}
isConnected() {
return this.entity.isConnected()
}
getType() {
return this.entity.getType()
}
}
customElements.define("u-pin", GraphPin);
/**
* @typedef {import("../graph/GraphNode").default} GraphNode
*/
@@ -1078,12 +1147,6 @@ class NodeTemplate extends SelectableDraggableTemplate {
*/
header(node) {
return html`
<div class="ueb-node-header">
<span class="ueb-node-name">
<span class="ueb-node-symbol"></span>
<span class="ueb-node-text">${node.entity.getNodeDisplayName()}</span>
</span>
</div>
`
}
@@ -1093,29 +1156,10 @@ class NodeTemplate extends SelectableDraggableTemplate {
* @returns The result html
*/
body(node) {
/** @type {PinEntity[]} */
let inputs = node.entity.CustomProperties.filter(v => v instanceof PinEntity);
let outputs = inputs.filter(v => v.isOutput());
let inputs = node.entity.CustomProperties.filter(v => v instanceof PinEntity$1);
inputs.filter(v => v.isOutput());
inputs = inputs.filter(v => v.isInput());
return html`
<div class="ueb-node-body">
<div class="ueb-node-inputs">
${inputs.map((input, index) => html`
<div class="ueb-node-input ueb-node-value-${input.type}">
<span class="ueb-node-value-icon ${inputs[index].connected ? 'ueb-node-value-fill' : ''}"></span>
${input.getPinDisplayName()}
</div>
`).join("") ?? ""}
</div>
<div class="ueb-node-outputs">
${outputs.map((output, index) => html`
<div class="ueb-node-output ueb-node-value-${output.type}">
${output.getPinDisplayName()}
<span class="ueb-node-value-icon ${outputs[index].connected ? 'ueb-node-value-fill' : ''}"></span>
</div>
`).join('') ?? ''}
</div>
</div>
`
}
@@ -1128,8 +1172,16 @@ class NodeTemplate extends SelectableDraggableTemplate {
return html`
<div class="ueb-node-border">
<div class="ueb-node-content">
${this.header(node)}
${this.body(node)}
<div class="ueb-node-header">
<span class="ueb-node-name">
<span class="ueb-node-symbol"></span>
<span class="ueb-node-text">${node.entity.getNodeDisplayName()}</span>
</span>
</div>
<div class="ueb-node-body">
<div class="ueb-node-inputs"></div>
<div class="ueb-node-outputs"></div>
</div>
</div>
</div>
`
@@ -1147,6 +1199,13 @@ class NodeTemplate extends SelectableDraggableTemplate {
}
node.style.setProperty("--ueb-position-x", node.location[0]);
node.style.setProperty("--ueb-position-y", node.location[1]);
/** @type {HTMLElement} */
let inputContainer = node.querySelector(".ueb-node-inputs");
/** @type {HTMLElement} */
let outputContainer = node.querySelector(".ueb-node-outputs");
let pins = node.getPinEntities();
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new GraphPin(v)));
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new GraphPin(v)));
}
}
@@ -1173,6 +1232,11 @@ class IntegerEntity extends Entity {
}
constructor(options = {}) {
if (options.constructor === Number || options.constructor === String) {
options = {
value: options
};
}
super(options);
this.value = Math.round(this.value);
}
@@ -1214,7 +1278,7 @@ class ObjectEntity extends Entity {
NodeGuid: GuidEntity,
ErrorType: new TypeInitialization(IntegerEntity, false),
ErrorMsg: new TypeInitialization(String, false, ""),
CustomProperties: [PinEntity]
CustomProperties: [PinEntity$1]
}
getAttributes() {
@@ -1390,6 +1454,14 @@ class GraphNode extends SelectableDraggable {
return new GraphNode(entity)
}
/**
*
* @returns {PinEntity[]}
*/
getPinEntities() {
return this.entity.CustomProperties.filter(v => v instanceof PinEntity$1)
}
connectedCallback() {
this.getAttribute("type")?.trim();
super.connectedCallback();
@@ -1406,8 +1478,9 @@ class GraphNode extends SelectableDraggable {
}
setLocation(value = [0, 0]) {
this.entity.NodePosX = value[0];
this.entity.NodePosY = value[1];
let nodeType = this.entity.NodePosX.constructor;
this.entity.NodePosX = new nodeType(value[0]);
this.entity.NodePosY = new nodeType(value[1]);
super.setLocation(value);
}
}
@@ -1439,7 +1512,7 @@ class Grammar {
None = _ => P.string("None").map(_ => new ObjectReferenceEntity({ type: "None", path: "" })).desc("none")
Boolean = _ => P.alt(P.string("True"), P.string("False")).map(v => v === "True" ? true : false).desc("either True or False")
Number = _ => P.regex(/[\-\+]?[0-9]+(?:\.[0-9]+)?/).map(Number).desc("a number")
Integer = _ => P.regex(/[\-\+]?[0-9]+/).map(v => new IntegerEntity({ value: v })).desc("an integer")
Integer = _ => P.regex(/[\-\+]?[0-9]+/).map(v => new IntegerEntity(v)).desc("an integer")
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")
Guid = _ => P.regex(/[0-9a-zA-Z]{32}/).map(v => new GuidEntity({ value: v })).desc("32 digit hexadecimal (accepts all the letters for safety) value")
@@ -1508,7 +1581,7 @@ class Grammar {
return r.PinReference
case FunctionReferenceEntity:
return r.FunctionReference
case PinEntity:
case PinEntity$1:
return r.Pin
case Array:
return P.seqMap(
@@ -1568,8 +1641,8 @@ class Grammar {
Pin = r => Grammar.CreateMultiAttributeGrammar(
r,
P.string("Pin"),
PinEntity,
attributeKey => Utility.objectGet(PinEntity.attributes, attributeKey)
PinEntity$1,
attributeKey => Utility.objectGet(PinEntity$1.attributes, attributeKey)
)
CustomProperties = r =>
P.string("CustomProperties")
@@ -1722,7 +1795,7 @@ class ObjectSerializer extends Serializer {
let result = `Begin Object Class=${this.writeValue(object.Class)} Name=${this.writeValue(object.Name)}
${this.subWrite([], 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$1).write(pin))
.join("")}
End Object`;
return result
@@ -1764,9 +1837,9 @@ class Paste extends Context {
nodes.forEach(node => {
const locationOffset = [
mousePosition[0] - left,
mousePosition[1] - top
mousePosition[1] - top,
];
node.addLocation(locationOffset);
node.addLocation(this.blueprint.compensateTranslation(locationOffset));
node.setSelected(true);
});
}
@@ -2319,8 +2392,8 @@ function initializeSerializerFactory() {
new ObjectSerializer()
);
SerializerFactory.registerSerializer(
PinEntity,
new GeneralSerializer(v => `Pin (${v})`, PinEntity, "", ",", true)
PinEntity$1,
new GeneralSerializer(v => `Pin (${v})`, PinEntity$1, "", ",", true)
);
SerializerFactory.registerSerializer(
FunctionReferenceEntity,

View File

@@ -11,6 +11,11 @@ export default class IntegerEntity extends Entity {
}
constructor(options = {}) {
if (options.constructor === Number || options.constructor === String) {
options = {
value: options
}
}
super(options)
this.value = Math.round(this.value)
}

View File

@@ -41,22 +41,6 @@ export default class PinEntity extends Entity {
return PinEntity.attributes
}
/**
*
* @returns {String}
*/
getPinDisplayName() {
return this.PinName
}
isConnected() {
return this.LinkedTo.length > 0
}
getType() {
return this.PinType.PinCategory ?? "object"
}
isInput() {
if (!this.bHidden && this.Direction !== "EGPD_Output") {
return true
@@ -68,4 +52,12 @@ export default class PinEntity extends Entity {
return true
}
}
isConnected() {
return this.LinkedTo.length > 0
}
getType() {
return this.PinType.PinCategory ?? "object"
}
}

View File

@@ -3,6 +3,7 @@ import ObjectEntity from "../entity/ObjectEntity"
import SelectableDraggable from "./SelectableDraggable"
import SerializerFactory from "../serialization/SerializerFactory"
import DragLink from "../input/DragLink"
import PinEntity from "../entity/PinEntity"
export default class GraphNode extends SelectableDraggable {
@@ -24,6 +25,14 @@ export default class GraphNode extends SelectableDraggable {
return new GraphNode(entity)
}
/**
*
* @returns {PinEntity[]}
*/
getPinEntities() {
return this.entity.CustomProperties.filter(v => v instanceof PinEntity)
}
connectedCallback() {
const type = this.getAttribute("type")?.trim()
super.connectedCallback()
@@ -40,8 +49,9 @@ export default class GraphNode extends SelectableDraggable {
}
setLocation(value = [0, 0]) {
this.entity.NodePosX = value[0]
this.entity.NodePosY = value[1]
let nodeType = this.entity.NodePosX.constructor
this.entity.NodePosX = new nodeType(value[0])
this.entity.NodePosY = new nodeType(value[1])
super.setLocation(value)
}
}

View File

@@ -3,13 +3,43 @@ import PinTemplate from "../template/PinTemplate"
export default class GraphPin extends GraphElement {
constructor() {
super({}, new PinTemplate())
constructor(entity) {
super(entity, new PinTemplate())
/** @type {import("../entity/PinEntity").default} */
this.entity
}
/*connectedCallback() {
connectedCallback() {
super.connectedCallback()
}*/
}
/**
*
* @returns {String}
*/
getPinDisplayName() {
return this.entity.PinName
}
getAttributes() {
return PinEntity.attributes
}
isInput() {
return this.entity.isInput()
}
isOutput() {
return this.entity.isOutput()
}
isConnected() {
return this.entity.isConnected()
}
getType() {
return this.entity.getType()
}
}
customElements.define("u-pin", GraphPin)

View File

@@ -37,9 +37,9 @@ export default class Paste extends Context {
nodes.forEach(node => {
const locationOffset = [
mousePosition[0] - left,
mousePosition[1] - top
mousePosition[1] - top,
]
node.addLocation(locationOffset)
node.addLocation(this.blueprint.compensateTranslation(locationOffset))
node.setSelected(true)
})
}

View File

@@ -21,7 +21,7 @@ export default class Grammar {
None = _ => P.string("None").map(_ => new ObjectReferenceEntity({ type: "None", path: "" })).desc("none")
Boolean = _ => P.alt(P.string("True"), P.string("False")).map(v => v === "True" ? true : false).desc("either True or False")
Number = _ => P.regex(/[\-\+]?[0-9]+(?:\.[0-9]+)?/).map(Number).desc("a number")
Integer = _ => P.regex(/[\-\+]?[0-9]+/).map(v => new IntegerEntity({ value: v })).desc("an integer")
Integer = _ => P.regex(/[\-\+]?[0-9]+/).map(v => new IntegerEntity(v)).desc("an integer")
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")
Guid = _ => P.regex(/[0-9a-zA-Z]{32}/).map(v => new GuidEntity({ value: v })).desc("32 digit hexadecimal (accepts all the letters for safety) value")

View File

@@ -1,4 +1,3 @@
import Blueprint from "../Blueprint"
import html from "./html"
import sanitizeText from "./sanitizeText"
import Template from "./Template"

View File

@@ -1,6 +1,7 @@
import html from "./html"
import PinEntity from "../entity/PinEntity"
import SelectableDraggableTemplate from "./SelectableDraggableTemplate"
import GraphPin from "../graph/GraphPin"
/**
* @typedef {import("../graph/GraphNode").default} GraphNode
@@ -14,12 +15,6 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
*/
header(node) {
return html`
<div class="ueb-node-header">
<span class="ueb-node-name">
<span class="ueb-node-symbol"></span>
<span class="ueb-node-text">${node.entity.getNodeDisplayName()}</span>
</span>
</div>
`
}
@@ -29,29 +24,10 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
* @returns The result html
*/
body(node) {
/** @type {PinEntity[]} */
let inputs = node.entity.CustomProperties.filter(v => v instanceof PinEntity)
let outputs = inputs.filter(v => v.isOutput())
inputs = inputs.filter(v => v.isInput())
return html`
<div class="ueb-node-body">
<div class="ueb-node-inputs">
${inputs.map((input, index) => html`
<div class="ueb-node-input ueb-node-value-${input.type}">
<span class="ueb-node-value-icon ${inputs[index].connected ? 'ueb-node-value-fill' : ''}"></span>
${input.getPinDisplayName()}
</div>
`).join("") ?? ""}
</div>
<div class="ueb-node-outputs">
${outputs.map((output, index) => html`
<div class="ueb-node-output ueb-node-value-${output.type}">
${output.getPinDisplayName()}
<span class="ueb-node-value-icon ${outputs[index].connected ? 'ueb-node-value-fill' : ''}"></span>
</div>
`).join('') ?? ''}
</div>
</div>
`
}
@@ -64,8 +40,16 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
return html`
<div class="ueb-node-border">
<div class="ueb-node-content">
${this.header(node)}
${this.body(node)}
<div class="ueb-node-header">
<span class="ueb-node-name">
<span class="ueb-node-symbol"></span>
<span class="ueb-node-text">${node.entity.getNodeDisplayName()}</span>
</span>
</div>
<div class="ueb-node-body">
<div class="ueb-node-inputs"></div>
<div class="ueb-node-outputs"></div>
</div>
</div>
</div>
`
@@ -83,5 +67,12 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
}
node.style.setProperty("--ueb-position-x", node.location[0])
node.style.setProperty("--ueb-position-y", node.location[1])
/** @type {HTMLElement} */
let inputContainer = node.querySelector(".ueb-node-inputs")
/** @type {HTMLElement} */
let outputContainer = node.querySelector(".ueb-node-outputs")
let pins = node.getPinEntities()
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new GraphPin(v)))
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new GraphPin(v)))
}
}

View File

@@ -2,50 +2,35 @@ import html from "./html"
import Template from "./Template"
/**
* @typedef {import("../entity/PinEntity").default} PinEntity
* @typedef {import("../graph/GraphPin").default} GraphPin
*/
export default class PinTemplate extends Template {
/**
* Computes the template for a pin in case it is an input.
* @param {PinEntity} pin Pin entity
* @returns The result html
*/
renderInputPin(pin) {
return html`
<div class="ueb-node-input ueb-node-value-${pin.getType()}">
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
${pin.getPinDisplayName()}
</div>
`
}
/**
* Computes the template for a pin in case it is an output.
* @param {PinEntity} pin Pin entity
* @returns The result html
*/
renderOutputPin(pin) {
return html`
<div class="ueb-node-output ueb-node-value-${pin.getType()}">
${output.getPinDisplayName()}
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
</div>
`
}
/**
* Computes the html content of the pin.
* @param {PinEntity} pin Pin entity
* @param {GraphPin} pin Pin entity
* @returns The result html
*/
render(pin) {
if (pin.isInput()) {
return this.renderInputPin(pin)
return html`
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
${pin.getPinDisplayName()}
`
} else {
return html`
${pin.getPinDisplayName()}
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
`
}
if (pin.isOutput()) {
return this.renderOutputPin(pin)
}
return ""
}
}
/**
* Applies the style to the element.
* @param {GraphPin} pin Element of the graph
*/
apply(pin) {
super.apply(pin)
pin.classList.add("ueb-node-" + pin.isInput() ? "input" : "output", "ueb-node-value-" + pin.getType())
}
}